1. 程式人生 > >[BX]和loop指令

[BX]和loop指令

圖片 http png debug 物理 sum 結果 問題 們的

1.[bx]表示內存的用法,loop指令的用法

技術分享圖片

語法格式

loop 標號

通常我們用loop指令來實現循環功能,cx中存放循環次數。

cpu執行指令過程

1.cx=cx-1

2.判斷cx的值是否為0

如果cx不等於0,跳轉到標號出執行

如果cx=0,執行loop後面的其它指令。

2.綜合應用loop和[BX]編程時,對於類型不一致(8位,16位)、數據超出範圍等情形的處理(結合5.3節程序5.3和5.5節實例)

在匯編程序中,數據不能以字母開頭。例:A000h在匯編程序中要寫為:0A000h

從ds中可以得到PSP的段地址SA,PSP的偏移地址為0,則物理地址為SA*16+0,可用段地址和偏移地址表示為:SA+10h:0

遇到loop指令時,可以用p指令執行,debug自動重復執行循環代碼,直到(cx)=0,也可以用g命令來達到目的。

類型不一致時,例:ffff:6單元中是一個字節單元,ax是一個16位寄存器,數據長度不一樣,如何賦值?

我們說的是“賦值”,就是說,讓ax中的數據的值(數據的大小)和ffff:0006單元中的數據的值(數據的大小)相等。8位數據01h和16位數據0001h的數據長度不一樣,但它們的值是相等的。那麽我們如何賦值,設ffff:0006單元中的數據是xxh,若要ax中的值和ffff:0006單元中的相等,ax中的數據應為00xxh。所以,若實現ffff:0006單元向ax賦值,應該令(ah)=0,(al)=(ffff6h)。

有兩個問題:類型的匹配和結界的不超界。具體的說,就是在做加法的時候,我們有兩種方法:

1.(dx)=(dx)+內存中的8位數據;

2.(dl)=(dl)+內存中的8位數據。

第一種方法中的問題是兩個運算對象的類型不匹配,第二種方法中的問題是結果有可能超界。解決這兩個看似矛盾的問題,目前的方法就是得用一個16位寄存器來做中介,將內存單元中的8位數據賦值到一個16位寄存器ax中,再將ax中的數據加到dx上,從而使兩個運算對象的類型匹配並且結果不會超界。

assume cs:code
code segment

         mov ax,0ffffh
         mov ds,ax
         mov bx,
0 ;初始化ds:bx指向ffff:0 mov dx,0 ;初始化累加寄存器dx,(dx)=0 mov cx,12 ;初始化循環計數寄存器cx,(cx)=12 s: mov al,[bx] mov ah,0 add dx,ax ; 間接向dx中加上((ds)*16+(bx))單元的數值 inc bx ; ds:bx指向下一個單元
loop s mov ax,4c00h
int 21h code ends end

3.debug工具中t命令、p命令、g命令用法

t命令

單步執行;遇loop會進入循環內部繼續單步執行;遇int會進入中斷程序內繼續單步執行;

p命令

單步執行;遇loop或int會當作整體執行,不進入內部單步執行;

g命令

執行到指定地址;或遇程序結束或int,則終止執行。

4.debug和masm在處理內存單元上的不同及問題處理方式

在debug中編程實現

mov ax,2000
mov ds,ax
mov al,[0]
mov bl,[1]
mov cl,[2]
mov dl,[3]

技術分享圖片

匯編源程序實現

assume cs:code
code segment

mov ax,2000h
mov ds,ax
mov al,[0]
mov bl,[1]
mov cl,[2]
mov dl,[3]

mov ax,4c00h
int 21h

code ends
end

技術分享圖片

可以看出,debug和編譯器masm對形如“mov ax,[0]”這類指令在解釋上的不同,debug和編譯器對這些指令中的“[idata]”有不同的解釋。debug將它解釋為“[idata]”是一個內存單元,“idata”是內存單元的偏移地址;而編譯器將“[idata]"解釋為“idata”。

那麽解決方法是,可將偏移地址送入bx寄存器,用[bx]的方式來訪問內存單元。比如我們可以這樣訪問2000:0單元。

mov ax,2000h
mov ds,ax     ;段地址2000h送入ds
mov bx,0      ;偏移地址0送入bx
mov al,[bx]   ;ds:bx單元中的數據送入al

[BX]和loop指令