檢測點3.1
(1) 在DEBUG中,用 "D 0:0 lf" 查看內存,結果如下:
0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88
下面的程序執行前,AX=0,BX=0,寫出每條匯編指令執行完后相關寄存器中的值
程序分析:
【1】首先確定ds值是0001H,如果偏移地址是0000H的話,它們物理地址是00010H;那么如果它的段地址是0000H(因為此時段地址是0000H)的情況下,它的偏移地址是從0010H開始的。因為它們的物理地址是唯一的,而且是同一個。
【2】經過上述分析后,我們確定ds:[0000]是指的0000:0010開始的內存單元(也就是debug第二行內存單元開始)。
【3】注意CPU訪問內存單元時,指令的操作對象決定了內存單元是字節型單元還是字型單元。
【4】debug中,內存單元從左到右是地址從低到高順序排列的。
【5】add是不帶進位的加法,如果遇到進位,那么進位值被截斷(舍去)。但它影響標志位。
【6】al、ah和ax是3個不同的寄存器,al存放運算結果產生的進位不會存放到ah中,雖然ah是高8位的8位寄存器。
結果如下:
mov ax,1
mov ds,ax
mov ax,[0000] ax= 2662H
mov bx,[0001] bx= E626H
mov ax,bx ax= E626H
mov ax,[0000] ax= 2662H
mov bx,[0002] bx= D6E6H
add ax,bx ax= FD48H
add ax,[0004] ax= 2C14H ;2ECCH+ FD48H=1 2C14H,其中進位截斷。
mov ax,0 ax= 0
mov al,[0002] ax= 00e6H
mov bx,0 bx= 0
mov bl,[000c] bx= 0026H
add al,bl ax= 000CH ;同理:E6H+26H=1 0CH,其中進位截斷
(2) 內存中的情況如圖3.6所示
各寄存器的初始值:cs=2000h,ip=0,ds=1000h,ax=0,bx=0;
程序分析:
【1】CPU總是從cs:ip指向的內存單元讀取指令並運行。故先從mov ax,6622H讀取並執行。
cs=2000H;ip=0003H; ds=1000H ;ax=6622H;bx=0000H
【2】執行jmp指令(段間直接跳轉),確定0ff0:0100的物理地址是:0ff0*10H+100H=10000H;故CPU從物理地址是10000H開始處讀取並執行代碼。正好在10000H單元開始有指令:mov ax,2000H。這也證明了物理地址是唯一的,基礎地址+偏移地址的組合是多種的。
cs=0ff0H;ip=0103H;ds=1000H;ax=2000H;bx=0000H
【3】開始執行下一個指令:mov ds,ax;
cs=0ff0H;ip=0105H;ds=2000H;ax=2000H;bx=0000H
【4】執行下一個指令:mov ax,[0008],由於ds指向了2000H段內存,[0008]代表了字型單元,值為C389H
cs=0ff0H;ip=0108H;ds=2000H;ax=C389H;bx=0000H
【5】執行下一個指令:mov ax,[0002],由於ds指向了2000H段內存,[0002]代表了字型單元,值為EA66H
cs=0ff0H;ip=010BH;ds=2000H;ax= EA66H;bx=0000H
答案:
【1】CPU執行序列為:
mov ax,6622H
jmp 0ff0:0100
mov ax,2000H
mov ds,ax
mov ax,[0008]
mov ax,[0002]
【2】CPU執行每條指令后,cs、ip和相關寄存器的值:
mov ax,6622H
cs=2000H;ip=0003H; ds=1000H ;ax=6622H;bx=0000H
jmp 0ff0:0100
cs=0ff0H;ip=0100H;ds=1000H;ax=6622H;bx=0000H
mov ax,2000H
cs=0ff0H;ip=0103H;ds=1000H;ax=2000H;bx=0000H
mov ds,ax
cs=0ff0H;ip=0105H;ds=2000H;ax=2000H;bx=0000H
mov ax,[0008]
cs=0ff0H;ip=0108H;ds=2000H;ax=C389H;bx=0000H
mov ax,[0002]
cs=0ff0H;ip=010BH;ds=2000H;ax=EA66H;bx=0000H
【3】再次體會,數據和指令(數據和程序)在內存中存儲是沒有區別的,是數據還是指令?需要看它具體的應用體現。如果cs:ip指向的內存單元,那么它就作為CPU指令讀取並執行。
程序分析:
【1】首先我們觀察這二段連續內存,都是8個字,程序中已經給出了ds指向了1000H段的內存單元。
【2】那么我們可以通過將20000H開始的內存段定義為一個堆棧段,長度是10H,使用push操作將1000H數據段數據逆序復制到我們定義的ss段中。
【3】注意體會push指令的壓棧操作。這程序是使用push指令復制數據
代碼完成如下:
mov ax,1000H
mov ds,ax
mov ax,2000H ;由於ss是段寄存器,必須間接賦值。
mov ss,ax ;使ss棧頂指向2000H段內存
mov sp,10H ;初始化棧頂指針,棧空狀態,向低地址發展
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]
(2)補全下面的程序,使其可以將10000H-1000FH中的8個字,逆序拷貝到20000H-2000FH中。
程序分析:這個程序是通過pop指令在內存中復制數據的。同上述基本差不多。
mov ax,2000H
mov ds,ax
mov ax,1000H
mov ss,ax ;使ss棧頂指向1000H段內存
mov sp,0 ;初始化棧頂指針,由於棧結構滿了,sp=0,向高地址發展
pop [e]
pop [c]
pop [a]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]