日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

更灵活的定位内存地址的方法---汇编学习笔记

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 更灵活的定位内存地址的方法---汇编学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

更靈活的定位內存地址的方法

前面,我們用[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 = 01111011B

7.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 start

debug運行查看是否:

先用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中的內容。

mov ax,2000H ;ax=2000h mov ds,ax ;ds=2000h mov bx,1000H ;bx=1000h mov ax,[bx] ;ax=00BEh mov cx,[bx+1] ;cx=0600h add cx,[bx+2] ;cx=0606h

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!’復制到它后面的數據區中。

assume cs:codesg,ds:datasg datasg segmentdb 'welcome to masm!'db '................' datasg ends

代碼段(答案):

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的程序
答案如下:

codesg segmentstart: mov ax,datasgmov ds,axmov si,0mov cx,8s: mov ax,[si]mov [si+16],axadd si,2loop smov ax,4c00hint 21hcodesg ends end start

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中的內容。

mov ax,2000h ;ax=2000h mov ds,ax ;ds=2000h mov bx,1000h ;bx=1000h mov si,0 ;si=0h mov ax,[bx+si] ;ax=00beh inc si ;si=1h mov cx,[bx+si] ;cx=0600h inc si ;si=2h mov di,si ;di=2h add cx,[bx+di] ;cx=0606h

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中的內容。

mov ax,2000h ;ax=2000h mov ds,ax ;ds=2000h mov bx,1000h ;bx=1000h mov si,0 ;si=0h mov ax,[bx+2+si] ;ax=0006h inc si ;si=1h mov cx,[bx+2+si] ;cx=6a00h inc si ;si=2h mov di,si ;di=2h mov bx,[bx+2+di] ;bx=226ah

7.10 不同的尋址方式的靈活應用

(1)[idata]用一個變量來表示地址,可用于直接定位一個內存單元。
(2)[bx]用一個變量來表示內存地址,可用于間接定位一個內存單元。
(3)[bx+idata]用一個變量和常量表示地址,可在一個起始地址的基礎上用變量間接定位一個內存單元。
(4)[bx+si]用兩個變量表示地址。
(5)[bx+si+idata]用兩個變量和一個常量表示地址。

問題 7.6
編程,將datasg段中每個單詞的頭一個字母改為大寫字母。

assume cs:codesg,ds:datasg datasg segmentdb '1. file 'db '2. edit 'db '3. search 'db '4. view 'db '5. options 'db '6. help ' datasg segmentcodesg segmentstart:;答案如下:mov ax,datasgmov ds,axmov bx,0mov cx,6s:mov al,[bx+3]and al,11011111Bmov [bx+3],aladd bx,10hloop smov ax,4c00hint 21h codesg ends end start

問題 7.7
編程,將datasg段中每個單詞改為大寫字母。

assume cs:codesg,ds:datasg datasg segmentdb 'ibm 'db 'dec 'db 'dos 'db 'vax ' datasg endscodesg segmentstart:;答案如下:mov ax,datasgmov ds,axmov bx,0mov cx,4s:mov dx,cxmov si,0mov cx,3s0:mov al,[bx+si]and al,11011111bmov [bx+si],alinc siloop s0add bx,10hmov cx,dxloop smov ax,4c00hint 21h codesg ends end start

其實,我們這里存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

總結

這一章,我們主要學習了尋址方式:

  • 尋址方式[bx(或 si、di)+idata]、[bx+si(或 di)]、[bx+si(或 di)+idata]的意義和應用。
  • 二重循環問題的處理
  • 棧的應用
  • 大小寫轉化的方法
  • and、or指令

  • 實驗6 實踐課程中的程序

    (1)將課程中所有講解過的程序上機調試,用Debug跟蹤其執行過程,并在過程中進一步理解所講內容。
    (2)編程,完成問題7.9中的程序。將下面datasg段的每個單詞的前4個字母改為大寫!

    assume cs:codesg,ss:stacksg,ds:datasgstacksg segmentdw 0,0,0,0,0,0,0,0 stacksg endsdatasg segmentdb '1. display 'db '2. brows 'db '3. replace 'db '4. modify ' datasg endscodesg segmentstart:mov ax,datasgmov ds,axmov bx,0mov cx,4s: push cxmov si,0mov cx,4s0:mov al,[bx+si+3]and al,11011111bmov [bx+si+3],alinc siloop s0add bx,16pop cxloop smov ax,4c00hint 21h codesg ends end start

    實驗結果如下:

    總結

    以上是生活随笔為你收集整理的更灵活的定位内存地址的方法---汇编学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。