匯編語言(王爽第三版)檢測點:9


檢測點:9.1

(1)

assume cs:code

data segment

    ???????

data ends

code segment

start:  mov ax,data

        mov ds,ax

        mov bx,0

        jmp word ptr [bx+1]

       

        mov ax,4c00H

        int 21H

code ends

end start

       若要使程序中jmp指令執行后,cs:ip指向程序的第一條指令,在data段中應定義哪些數據?

程序分析:

       1) 這個指令jmp word ptr [bx+1]是一個段內近轉移,它只是修改了ip的值。它的轉移地址在內存中。明確:[bx+1]在此例子中是只的data段的第二個字節。

       2)我們發現ds:bx指向了data段,word ptr [bx+1]指向的是data段中的第二個字節開始的字單元,也就是說它所指向的該字單元的內容。這個內容就是jmp跳轉的偏移地址。

       3)word ptr [bx+1]指的是一個字單元,也就是說是2個字節,也就是說在data段中是第2和第3個字節,如果jmp轉移到程序第一條指令,也就是說ip的值應為:00 00即可;我們要保證這二個字節的值是00 00就行。

       4)要想jmp跳轉到start標號處,它的ip值是offset start即可(在匯編語言層面我們也不必關心它們代表的具體ip值是多少);也就是說:(ds:[bx+1])==offset start,那么在data段中定義的第二個字必須是offset start。至於offset start具體代表的二進制碼是什么,那是編譯器的事情。

       5)第一個字節,你隨意定義成什么都行。

       這個結果是多個:

    dw 00xxH, offset start          ;xx代表任意數值(一個字節的)

       講解:此時借用的是00xxH的高位字節值,00

    db x,0,0                        ;x代表任意數值(一個字節的)

    dd 0                            ;2個字的內存單元,00 00 00 00

db 3 dup (0)

dw 2 dup (0)

dd 0

       簡單來說就是,只要ds:[bx+1]起始地址的兩個字節為0就可以了

      

       (2)程序如下:

assume cs:code

data segment

    dd 12345678H

data ends

code segment

start:  mov ax,data

        mov ds,ax

        mov bx,0

        mov [bx], offset start

        mov [bx+2], code

        jmp dword ptr ds:[0]

       

        mov ax,4c00H

        int 21H

code ends

end start

       補全程序,使cs:ip指向程序的第一條指令。

       程序分析:

              1)在data段中定義了一個雙字的值,占用4個字節,內存中是12 34 56 78

        2)jmp dword ptr ds:[0]代表的含義是,此指令是段間轉移的指令,cs和ip是存儲在一個雙字的單元中,其中高16位存儲的是cs值,低16位存儲的是ip值。

              3) [bx]代表了低16位的值==ip。[bx+2]代表了高16位的值==cs。

              4)也就是說保證data段中前2個字節是ip的值,第3,4字節是cs的值就可以。

              5)答案也就多了。

        [bx]==ip

        offset start

        ptr word 0

        0000H

        bx             

        [bx+2] ==cs

        cs

        code

       (3)用Debug查看內存,結果如下:

2000:1000 BE 00 06 00 00 00 ......

則此時,CPU執行指令:

mov ax,2000h

mov es,ax

jmp dword ptr es:[1000h]

程序分析:

1)通過上面二條指令,es指向了段地址是2000H的內存段。

2)jmp dword ptr es:[1000h]指令的含義:是一個段間轉移指令,指令的轉移地址在內存中,該內存單元是一個雙字單元(32位的單元),也就是說在1000H地址開始,低16位存儲的是ip的值,高16位存儲的是cs的值。

3)我們在debug內存存儲顯示中,不難發現,低16位是BE 00,也就是它的值是00BE。高16位是0600,也就是它的值是0006H,得出結論:(cs)= 0006H ,(ip)= 00BEH

 

檢測點9.2

       補全編程,利用jcxz指令,實現在內存2000H段中查找第一個值為0的字節,找到后,將它的偏移地址存儲在dx中。

assume cs:code

code segment

 start: mov ax,2000h

        mov ds,ax

        mov bx,0

     s:               

                     

                     

                     

        jmp short s

    ok: mov dx,bx

        mov ax ,4c00h

        int 21h

code ends

end start

       程序分析:

       標號s前面是將ds:bx指向了段地址為2000H的內存段。s標號到jmp short s是一個循環(死循環,除非有跳出語句)。

       這里我們需要jcxz有條件轉移語句來實現循環的跳出,jcxz的邏輯表達式只有一個就是(cx)=0,想法將cx的內容賦值為ds:bx,也就是說從ds:[0]開始,逐個字節的將單元內容賦值給cx,然后執行jcxz語句。

       由於是逐個字節的比較,bx的偏移量應該是以字節為單元。我們使用的cx寄存器是16位的,我們只需要低8位的cl寄存器就可以了。為了保證ch為0,首先必須置零。它們組合在一起就是cx的整體值(dh+dl)

       需填充的第一行:mov cl,[bx]         ;將2000段內存逐個字節賦值給cl

                     第二行:mov ch, 0           ;保證高8位為0          

                     第三行:jcxz ok                  ;判斷cx值,如果cx=0,跳轉到ok標號

                     第四行:inc bx                   ;cx!=0,繼續執行jcxz后面的語句。遞增bx,

       完整的程序是:

assume cs:code

code segment

 start: mov ax,2000h

        mov ds,ax

        mov bx,0

     s: mov cl[bx]

         mov ch 0 

        jcxz ok   

        inc bx    

        jmp short s

    ok: mov dx,bx

        mov ax ,4c00h

        int 21h

code ends

end start

 

檢測點9.3

       補全編程,利用loop指令,實現在內存2000H段中查找第一個值為0的字節,找到后,將它的偏移地址存儲在dx中。

assume cs:code

code segment

start:  mov ax,2000h

        mov ds,ax

        mov bx,0

      s:mov cl,[bx]

        mov ch,0

        inc cx

        inc bx

        loop s

     ok:dec bx

        mov dx,bx

        mov ax,4c00h

        int 21h

code ends

end start

       程序分析:

       1)保證這個loop循環的動力是:cx!=0,首先搞清這點。

       2)  如果ds:[0]=0情況下。如果我們使用jcxz指令,只有這種情況滿足條件,第一個字節為0.故不能使用jcxz指令。

       3)理解loop指令的動作,首先是(cx)=(cx)-1.然后才是跳轉到標號執行。

       4)添加inc cx指令

       如果第一個字節是0情況,inc cx導致(cx)=1,執行到loop指令時,首先(cx)=(cx)-1,導致(cx)=0,loop順序執行下面的指令(也就是標號ok的指令)。

       如果第一個字節非0情況,inc cx導致(cx)>1,執行到loop指令是,首先(cx)=(cx)-1,導致(cx)> 0(不為0),loop跳轉到s標號處執行代碼。

       5)答案:inc cx


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM