更灵活的定位内存地址的方法---汇编学习笔记
更靈活的定位內存地址的方法
前面,我們用[0]、[bx]的方法,在訪問內存的指令中,定位內存單元的地址。本章將用更靈活的方式來定位內存地址。
7.1 and和or指令
(1)and指令:邏輯與指令,按位進行與運算。例如:
mov al,01100011B and al,00111011B ;執行后:al = 00100011B(2)or指令:邏輯或指令,按位進行或運算。例如:
mov al,01100011B or al,00111011B ;執行后:al = 01111011B7.2 關于ASCII碼
略
7.3 以字符形式給出的數據
用‘……’的方式指明數據是以字符的形式給出,編譯器將它們轉化為相應的ASCII碼。如下:
assume cs:code,ds:data data segmentdb 'unIX' ;相當于 db 75H,6EH,49H,58Hdb 'foRK' ;同理,下面的也是 data endscode segment start: mov al,'a'mov bl,'b'mov ax,4c00hint 21h code ends end startdebug運行查看是否:
先用r命令分析一下data段的地址,因“ds=075A”,所以程序從076AH段開始,data段又是程序中的第一個段,它就在程序的起始處,所以它的段地址為0B3DH。
7.4 大小寫轉換的問題
考慮這樣一個問題,在codesg中填寫代碼,將datasg中的第一個字符串轉化為大寫,第二個字符串轉化為小寫。
assume cs:codesg,ds:datasg datasg segmentdb 'BaSic'db 'iNfOrMaTiOn' datasg ends codesg segmentstart: codesg ends ends start主要問題是怎么判斷一個字母是大寫還是小寫?不過我們好像沒有學過如何判斷一個字母大小寫的指令。所以該怎么辦呢?
我們觀察發現,ASCII碼的二進制形式有一個規律!如下:
因此,我們可以用剛剛學過的and和or來做這個實驗!這里指出方法:
變成大寫:只要and al,11011111B
變成小寫:只要or al,00100000B
7.5 [bx+idata]
指令mov ax,[bx+200]中的[bx+200]數學化的描述:(ax) = ((ds)*16+(bx)+200)。
問題 7.1
用Debug查看內存,結果如下:
2000:1000 BE 00 06 00 00 00 …
寫出下面的程序執行后,ax、bx、cx中的內容。
7.6 用[bx+idata]的方式進行數組的處理
我們經常用的一個策略,這里直接略過吧!
7.7 SI和DI
si和di是8086CPU中和bx功能相近的寄存器,si和di不能夠分成兩個8位寄存器來使用。
下面3組實現了相同的功能:
;第一組 mov bx,0 mov ax,[bx] mov ax,[bx+123];第二組 mov si,0 mov ax,[si] mov ax,[si+123];第三組 mov di,0 mov ax,[di] mov ax,[di+123]問題 7.2
用si和di實現字符串’welcome to masm!’復制到它后面的數據區中。
代碼段(答案):
codesg segmentstart: mov ax,datasgmov ds,axmov si,0mov di,10hmov cx,8s: mov ax,[si]mov [di],axadd si,2add di,2loop smov ax,4c00hint 21hcodesg ends end start問題 7.3
用更少的代碼,實現問題7.2的程序
答案如下:
7.8 [bx+si]和[bx+di]
指令mov ax,[bx+si]中的[bx+si]數學化的描述:(ax) = ((ds)*16+(bx)+(si))。
問題 7.4
用Debug查看內存,結果如下:
2000:1000 BE 00 06 00 00 00 …
寫出下面的程序執行后,ax、bx、cx中的內容。
7.9 [bx+si+idata]和[bx+di+idata]
指令mov ax,[bx+si+idata]中的[bx+si+idata]數學化的描述:(ax) = ((ds)*16+(bx)+(si)+(idata))。
問題 7.5
用Debug查看內存,結果如下:
2000:1000 BE 00 06 00 6A 22 …
寫出下面的程序執行后,ax、bx、cx中的內容。
7.10 不同的尋址方式的靈活應用
(1)[idata]用一個變量來表示地址,可用于直接定位一個內存單元。
(2)[bx]用一個變量來表示內存地址,可用于間接定位一個內存單元。
(3)[bx+idata]用一個變量和常量表示地址,可在一個起始地址的基礎上用變量間接定位一個內存單元。
(4)[bx+si]用兩個變量表示地址。
(5)[bx+si+idata]用兩個變量和一個常量表示地址。
問題 7.6
編程,將datasg段中每個單詞的頭一個字母改為大寫字母。
問題 7.7
編程,將datasg段中每個單詞改為大寫字母。
其實,我們這里存cx應該需要用棧來存儲。這是我們常用的方法,也是遞歸的本質。
如下:
assume cs:codesg,ss:stacksg,ds:datasg ;增加了棧空間 stacksg segmentdw 0,0,0,0,0,0,0,0 stacksg endsdatasg segmentdb 'ibm 'db 'dec 'db 'dos 'db 'vax ' datasg endscodesg segmentstart:;答案如下:mov ax,datasgmov ds,axmov bx,0mov cx,4s:push cx ;這里改變了mov si,0mov cx,3s0:mov al,[bx+si]and al,11011111bmov [bx+si],alinc siloop s0add bx,10hpop cx ;這里也改變了loop smov ax,4c00hint 21h codesg ends end start總結
這一章,我們主要學習了尋址方式:
實驗6 實踐課程中的程序
(1)將課程中所有講解過的程序上機調試,用Debug跟蹤其執行過程,并在過程中進一步理解所講內容。
(2)編程,完成問題7.9中的程序。將下面datasg段的每個單詞的前4個字母改為大寫!
實驗結果如下:
總結
以上是生活随笔為你收集整理的更灵活的定位内存地址的方法---汇编学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年中国健康险行业创新研究报告
- 下一篇: 你觉得你有那些特质让你比别人更适合做产品