<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      四個太陽

      導(dǎo)航

      實驗4 匯編應(yīng)用編程和c語言程序反匯編分析

      一、實驗結(jié)論

      1.實驗任務(wù)1

      編程:在屏幕中間分別顯示綠色、綠底紅色、白底藍(lán)色的字符串'welcome to masm!'

      實現(xiàn)以上實驗任務(wù)的源代碼task1.asm如下所示:

       1 assume cs:code, ds:data
       2 data segment
       3     db 'welcome to masm!' ;存放字符的數(shù)據(jù)
       4     db 00000010B, 00100100B, 01110001B  ;存放字符顏色屬性的數(shù)據(jù)
       5 data ends
       6 code segment
       7 start:mov ax, data
       8     mov ds, ax  ;設(shè)置數(shù)據(jù)段地址,指明數(shù)據(jù)從哪里來
       9     mov ax, 0b800H
      10     mov es, ax  ;設(shè)置附加段地址,指明數(shù)據(jù)到哪里去
      11     mov bx, 16  ;獲取顏色數(shù)據(jù)的偏移地址
      12     mov di, 1824  ;附加段數(shù)據(jù)的偏移地址
      13     mov cx, 3  ;設(shè)置循環(huán)次數(shù)為3
      14 s1: mov si, 0  ;數(shù)據(jù)段數(shù)據(jù)的偏移地址
      15     push cx  ;使用cx之前保存其原來的數(shù)據(jù)
      16     mov cx, 16  ;設(shè)置循環(huán)次數(shù)為16
      17 s2: mov al, ds:[si]  ;取第(si+1)個字符數(shù)據(jù)
      18     mov ah, ds:[bx]  ;取第(bx-15)個顏色屬性數(shù)據(jù)
      19     mov es:[di], ax  ;將攜帶顏色屬性的字符寫入到顯存中
      20     add di ,2  ;附加段的偏移地址自增2,以便下一次寫入字符數(shù)據(jù)
      21     inc si  ;取下一個字符的ASCII碼
      22     loop s2
      23     add di, 128  ;開始寫入下一行
      24     inc bx  ;改變下一行字符的顏色屬性
      25     pop cx  ;恢復(fù)cx的原先值
      26     loop s1
      27     mov ah, 4ch
      28     int 21h
      29 code ends
      30 end start

      將上述源程序task1.asm匯編、鏈接為程序task1.exe,其運行結(jié)果如下所示:

      實現(xiàn)思路:

        對于本實驗任務(wù)來說,最為關(guān)鍵的還是需要理解 80×25 彩色模式是怎樣的一個模式。而了解了80×25 彩色模式之后就可以推算出字符應(yīng)該寫入到

      顯存的何處位置,才會有中央展示的效果。80×25的彩色字符模式,即一屏25行80列。每一行顯示一個字符需要兩個字節(jié)(低位字節(jié)存放字符的ASCⅡ

      碼值,高位字節(jié)存放字符的顯示屬性),一共160個字節(jié)。默認(rèn),在顯存第0列顯示時,對應(yīng)的顯存空間為B8000H ~ B8F9FH。這里展示我們需要寫入

      三行數(shù)據(jù)的顯存偏移地址:

      由80×25的彩色組織模式可以得出,我們需要連續(xù)寫入32個字節(jié)的數(shù)據(jù)。從上述表中可以看出我們需要在偏移地址為1760位置處開始寫入數(shù)據(jù),但是在

      1760處開始寫入數(shù)據(jù)的話,顯示的數(shù)據(jù)就不是在屏幕中央了。所以,根據(jù)寫入的32字節(jié)數(shù)據(jù)以及1760~1919這個范圍,我們可以計算出在中央顯示數(shù)據(jù)

      的顯存偏移地址為[(1760+80)-16]=1824,同時也可以計算出下一行數(shù)據(jù)應(yīng)該寫入的顯存偏移地址為(1824+160)=1984。但是為了只使用一個di寄存器來

      間接尋址,我們需要考慮第一行最后一個數(shù)據(jù)后到第二行第一個數(shù)據(jù)開始所相差的字節(jié)數(shù)為[(80-16)*2] = 128。這便是“add di, 128”這條語句的由來。解

      決了這些問題之后,只需要考慮使用雙重循環(huán)即可,內(nèi)層循環(huán)負(fù)責(zé)寫入一行數(shù)據(jù),外層循環(huán)控制寫入幾行數(shù)據(jù)。設(shè)置雙重循環(huán)期間需要注意cx寄存器的

      使用,在使用cx控制內(nèi)層循環(huán)的時候需要將原cx的值保存到棧當(dāng)中,然后再去設(shè)置cx寄存器的值。

      2. 實驗任務(wù)2

      實驗任務(wù):編寫子程序printStr,實現(xiàn)以指定顏色在屏幕上輸出字符串。調(diào)用它,完成字符串輸出。

      使用任意一款文本編輯器,編寫8086匯編源程序task2.asm。源代碼如下:

       1 assume cs:code, ds:data
       2 data segment
       3     str db 'try', 0
       4 data ends
       5 
       6 code segment
       7 start:  
       8     mov ax, data
       9     mov ds, ax
      10 
      11     mov si, offset str  ;data數(shù)據(jù)段的間接尋址方式
      12     mov al, 2  ;設(shè)置顏色入口參數(shù)為綠色
      13     call printStr  ;調(diào)用子程序printStr
      14 
      15     mov ah, 4ch
      16     int 21h
      17 
      18 printStr:
      19     push bx
      20     push cx
      21     push si
      22     push di
      23     ;將寄存器的狀態(tài)保存到棧中
      24     mov bx, 0b800H
      25     mov es, bx  ;設(shè)置附加段地址,指明數(shù)據(jù)到哪里去
      26 s:  mov cl, [si]  ;將data數(shù)據(jù)段中偏移地址為si的字節(jié)數(shù)據(jù)存放到cl寄存器中
      27     mov ch, 0  ;將寄存器ch設(shè)置為0
      28     jcxz over  ;如果cx寄存器的值為零則跳轉(zhuǎn)到over繼續(xù)執(zhí)行;否則,不作任何操作
      29     mov ch, al  ;將顏色入口參數(shù)綠色放到ch寄存器中
      30     mov es:[di], cx  ;將帶有顏色屬性的字符寫入到顯存空間中
      31     inc si  ;取data數(shù)據(jù)段中的下一個字節(jié)數(shù)據(jù)
      32     add di, 2  ;附加段的偏移地址自增2,以便下一次寫入
      33     jmp s  ;無條件跳轉(zhuǎn)到s繼續(xù)執(zhí)行
      34 
      35 over:  ;從棧中恢復(fù)寄存器的狀態(tài)
      36     pop di
      37     pop si
      38     pop cx
      39     pop bx
      40     ret
      41 
      42 code ends
      43 end start

      將上述匯編源程序task2.asm匯編、鏈接成程序task2.exe,其運行結(jié)果如下所示:

      對源程序task2.asm做如下的修改:

      把line3改為:

      1 str db 'another try', 0

      把line12改為:

      1 mov al, 4

      將更改后的匯編源程序task2.asm匯編、鏈接成程序task2.exe,其運行結(jié)果如下所示:

      問題分析:

      (1)line19-22, line36-39,這組對稱使用的push、pop,這樣用的目的是什么?

        答:由于line24~line34之間的匯編代碼改變了bx、cx、si、di這四個寄存器的值,而且這些寄存器的改變是出現(xiàn)在子程序當(dāng)中的。那么在子程序被調(diào)用的

          時候這四個寄存器的原有值會被更改,當(dāng)子程序返回之前將四個寄存器的原值從棧中恢復(fù),就不會導(dǎo)致主調(diào)函數(shù)中的寄存器值出現(xiàn)意外的值。其目

          的就是在子程序被調(diào)用之后將各寄存器的狀態(tài)恢復(fù)到子程序被調(diào)用之前的狀態(tài)。

      (2)ine30的功能是什么?

        答:line30行的代碼內(nèi)容為“mov es:[di], cx”。首先,根據(jù)源代碼先前描述知道寄存器es的值為B800H,而di初始值為0。其次,cx的低位是存儲字符的

          ASCII值(字符的ASCII值來自于data數(shù)據(jù)段),而cx的高位是存儲字符顏色的屬性值(屬性值來自于入口參數(shù)al)。那么“mov es:[di], cx”的功能

          就是“將帶有顏色屬性的字?jǐn)?shù)據(jù)字符寫入到地址為B800:0的顯存空間中”。

      3. 實驗任務(wù)3

      使用任意一款文本編輯器,編寫8086匯編源程序task3.asm。源代碼如下:

       1 assume cs:code, ds:data
       2 data segment
       3         x dw 1984
       4         str db 16 dup(0)
       5 data ends
       6 
       7 code segment
       8 start:  
       9         mov ax, data
      10         mov ds, ax
      11         mov ax, x
      12         mov di, offset str
      13         call num2str
      14 
      15         mov ah, 4ch
      16         int 21h
      17 
      18 num2str:
      19         push ax
      20         push bx
      21         push cx
      22         push dx
      23         
      24         mov cx, 0
      25         mov bl, 10
      26 s1:      
      27         div bl
      28         inc cx
      29         mov dl, ah
      30         push dx
      31         mov ah, 0
      32         cmp al, 0
      33         jne s1
      34 s2:        
      35         pop dx
      36         or dl, 30h
      37         mov [di], dl
      38         inc di
      39         loop s2
      40         
      41         pop dx
      42         pop cx
      43         pop bx
      44         pop ax
      45 
      46         ret
      47 code ends
      48 end start

      實驗任務(wù):

      (1)對task3.asm進(jìn)行匯編、鏈接,得到可執(zhí)行程序后,在debug中使用u命令反匯編,使用g命令執(zhí)行到line15(程序退出之前),使用d命令查看數(shù)據(jù)段

        內(nèi)容,觀察是否把轉(zhuǎn)換后的數(shù)字字符串'1984'存放在數(shù)據(jù)段中str標(biāo)號后面的單元。

      (2)對task3.asm源代碼進(jìn)行修改、完善,把task2.asm中用于輸出以0結(jié)尾的字符串的子程序加進(jìn)來,實現(xiàn)對轉(zhuǎn)換后的字符串進(jìn)行輸出。

         答:實現(xiàn)對轉(zhuǎn)換后的字符串進(jìn)行輸出的task3.asm完整源程序如下所示:

       1 assume cs:code, ds:data
       2 data segment
       3         x dw 1984
       4         str db 16 dup(0)
       5 data ends
       6 
       7 code segment
       8 start:  
       9         mov ax, data
      10         mov ds, ax
      11         mov ax, x
      12         mov di, offset str
      13         call num2str
      14         mov al, 2  ;設(shè)置顏色入口參數(shù)為綠色
      15         call printStr  ;調(diào)用printStr子程序
      16 
      17         mov ah, 4ch
      18         int 21h
      19 
      20 num2str:
      21         push ax
      22         push bx
      23         push cx
      24         push dx
      25         
      26         mov cx, 0
      27         mov bl, 10
      28 s1:      
      29         div bl
      30         inc cx
      31         mov dl, ah
      32         push dx
      33         mov ah, 0
      34         cmp al, 0
      35         jne s1
      36 s2:        
      37         pop dx
      38         or dl, 30h
      39         mov [di], dl
      40         inc di
      41         loop s2
      42         
      43         pop dx
      44         pop cx
      45         pop bx
      46         pop ax
      47 
      48         ret
      49 
      50 printStr:
      51     push bx
      52     push cx
      53     push si
      54     push di
      55 
      56     mov bx, 0b800H
      57     mov es, bx
      58     mov di, 0
      59     mov si, offset str  ;將數(shù)據(jù)段的偏移地址指向存放數(shù)字字符的str
      60 s:      mov cl, [si]
      61     mov ch, 0
      62     jcxz over
      63     mov ch, al
      64     mov es:[di], cx
      65     inc si
      66     add di, 2
      67     jmp s
      68 
      69 over:   pop di
      70     pop si
      71     pop cx
      72     pop bx
      73     ret
      74 
      75 code ends
      76 end start

      將更改后的匯編源程序task3.asm匯編、鏈接成程序task3.exe,其運行結(jié)果如下所示:

      4. 實驗任務(wù)4

      使用任意一款文本編輯器,編寫8086匯編源程序task4.asm。源代碼如下:

       1 assume cs:code, ds:data
       2 data segment
       3         str db 80 dup(?)
       4 data ends
       5 
       6 code segment
       7 start:  
       8         mov ax, data
       9         mov ds, ax
      10         mov si, 0
      11 
      12 s1:        
      13         mov ah, 1
      14         int 21h
      15         mov [si], al
      16         cmp al, '#'
      17         je next
      18         inc si
      19         jmp s1
      20 next:
      21         mov cx, si
      22         mov si, 0
      23 s2:     mov ah, 2
      24         mov dl, [si]
      25         int 21h
      26         inc si
      27         loop s2
      28 
      29         mov ah, 4ch
      30         int 21h
      31 code ends
      32 end start

      將上述的task4.asm匯編、鏈接得到程序task4.exe。運行此程序然后輸入一個字符串并以#結(jié)束,程序運行結(jié)果如下所示:

       實驗任務(wù):

      (1)line12-19實現(xiàn)的功能是?

      1 mov ah, 1
      2 int 21h  ;使用軟中斷的1號子功能,從鍵盤中讀入一個字符
      3 mov [si], al  ;將從鍵盤中讀入的一個字符存放到data數(shù)據(jù)段中
      4 cmp al, '#'  ;將讀入的字符與'#'比較
      5 je next  ;如果讀入的字符是'#',那么跳轉(zhuǎn)到next程序段繼續(xù)執(zhí)行;否則不作任何操作
      6 inc si  ;data數(shù)據(jù)段的偏移地址自增1
      7 jmp s1  ;繼續(xù)讀入下一個字符    

        答:綜合上述匯編代碼注釋,line12-19實現(xiàn)的功能是“一直從鍵盤讀入字符,并將讀入的字符存放到data數(shù)據(jù)段當(dāng)中,直到遇到輸入符號為'#'為止”。

      (2)line21-27實現(xiàn)的功能是?

      1     mov cx, si  ;設(shè)置循環(huán)的執(zhí)行次數(shù)為讀入字符的個數(shù)
      2     mov si, 0  ;數(shù)據(jù)段中取數(shù)據(jù)的間接尋址方式
      3 s2: mov ah, 2 
      4     mov dl, [si]  ;將數(shù)據(jù)段中偏移量為si的字節(jié)數(shù)據(jù)存放到dl寄存器中
      5     int 21h  ;使用軟中斷的2號子功能,在顯示屏上輸出存放在dl中的字符
      6     inc si  ;取data段的下一個字節(jié)數(shù)據(jù)
      7     loop s2

        答:綜合上述匯編代碼注釋,line21-27實現(xiàn)的功能是“將存放在data數(shù)據(jù)段中的字符打印到顯示屏上,打印的字符個數(shù)就是讀入的字符個數(shù)”。

      5. 實驗任務(wù)5

      在visual studio集成環(huán)境中,編寫一個簡單的包含有函數(shù)調(diào)用的c程序。代碼如下:

       1 #include<stdio.h>
       2 int sum(int, int);
       3 
       4 int main() {
       5     int a = 2, b = 7, c;
       6     c = sum(a, b);
       7     return 0;
       8 }
       9 
      10 int sum(int x, int y) {
      11     return (x + y);
      12 }

      在line6, line11分別設(shè)置斷點,在調(diào)試模式下,查看反匯編代碼。line6的反匯編代碼如下圖所示:

       line11的反匯編代碼如下圖所示:

      實驗任務(wù):

      分析反匯編代碼,從匯編的角度,觀察高級語言中參數(shù)傳遞和返回值是通過什么實現(xiàn)的,以及參數(shù)的入棧順序,返回值的帶回方式。

      line6反匯編代碼的部分注釋:

           5:     int a = 2, b = 7, c;
       mov         dword ptr [ebp-8],2  ;在main函數(shù)棧幀中距棧底為8的位置定義雙字變量a并為其賦初值2
       mov         dword ptr [ebp-14h],7  ;在main函數(shù)棧幀中距棧底為14的位置定義雙字變量b并為其賦初值7
           6:     c = sum(a, b);
       mov         eax,dword ptr [ebp-14h]  
       push        eax  ;先將雙字變量b壓棧
       mov         ecx,dword ptr [ebp-8]  
       push        ecx  ;然后將雙字變量a壓棧
       call        0040137F  
       add         esp,8  
       mov         dword ptr [ebp-20h],eax  ;在main函數(shù)棧幀中距棧底為20的位置定義雙字變量b并為其賦sum函數(shù)的返回值eax
           7:     return 0;
       xor         eax,eax  ;將eax快速置零
           8: }

      line11反匯編代碼的部分注釋:

         10: int sum(int x, int y) {
       push        ebp  ;使用棧底指針寄存器之前,先將其原先值保存到棧中
       mov         ebp,esp  ;原棧頂變?yōu)樾聴5祝梢钥醋鱯um函數(shù)壓棧,此時棧底為main方法棧幀
       sub         esp,0C0h  ;重新設(shè)置棧頂指針寄存器的值,為新棧開辟內(nèi)存空間
       push        ebx  
       push        esi  
       push        edi  ;保存寄存器狀態(tài)以便恢復(fù)
       lea         edi,[ebp+FFFFFF40h]  
       mov         ecx,30h  
       mov         eax,0CCCCCCCCh  
       rep stos    dword ptr es:[edi]  ;串傳送指令,將eax寄存器的值轉(zhuǎn)送到es:[edi]的內(nèi)存空間中,傳送方向取決于DF標(biāo)志寄存器的值,而傳送次數(shù)取決于ecx的值。
       mov         ecx,40C003h 
       call        0040120D  
          11:     return (x + y);
       mov         eax,dword ptr [ebp+8]  ;在main函數(shù)棧幀中取距原esp為8的雙字?jǐn)?shù)據(jù)即副本a,注意main函數(shù)中定義的a變量存儲在原ss:[ebp-8]的位置。
       add         eax,dword ptr [ebp+0Ch];在main函數(shù)棧幀中取距原esp為12的雙字?jǐn)?shù)據(jù)即副本b,然后與eax即副本a做加法運算并將運算結(jié)果送回eax中,
                            ;注意main函數(shù)中定義的變量b存儲在原ss:[ebp-14]的位置。
          12: }
       pop         edi  
       pop         esi  
       pop         ebx  ;將寄存器的狀態(tài)復(fù)原
       add         esp,0C0h  ;還原esp,與“sub esp,0C0h”操作相對應(yīng)
       cmp         ebp,esp  
       call        00401217  
       mov         esp,ebp  ;新棧底恢復(fù)為原棧頂,相當(dāng)于sum函數(shù)出棧,此時棧中只有main方法
       pop         ebp  ;還原原棧底
      ret

        答:根據(jù)上述反匯編代碼的注釋分析,從匯編的角度來看,高級語言中參數(shù)傳遞是通過棧來實現(xiàn)的,并且靠近主調(diào)函數(shù)棧頂中的參數(shù)相當(dāng)于是形參,

          而靠近主調(diào)函數(shù)棧底中的參數(shù)相當(dāng)于實參,這就是在高級語言的值傳遞過程中,形參和實參互不影響的原因。然后被調(diào)函數(shù)的返回值在該例中

          是通過eax寄存器來存儲的,程序返回到主調(diào)函數(shù)可以通過eax寄存器來獲取被調(diào)函數(shù)的返回值。至于函數(shù)調(diào)用過程中參數(shù)的如入棧順序可以從

          line6的反匯編代碼中看出,在該例主調(diào)函數(shù)的函數(shù)調(diào)用過程中,參數(shù)b先入棧,參數(shù)a后入棧;而在被調(diào)函數(shù)的執(zhí)行過程中,副本a先被訪問,

          副本b后被訪問。

      posted on 2020-12-15 22:51  四個太陽  閱讀(244)  評論(2)    收藏  舉報

      主站蜘蛛池模板: 免费无码va一区二区三区| 欧美人与动人物牲交免费观看| 男人扒女人添高潮视频| 五月婷婷久久中文字幕| 亚洲一区二区av观看| 精品无码一区二区三区的天堂| 国产亚洲999精品AA片在线爽| 久久精品亚洲国产综合色| 人人人爽人人爽人人av| 国产中文字幕精品视频| 日韩一区二区三区无码a片| 国产欧美日韩亚洲一区二区三区 | 欧美极品色午夜在线视频| 国产成人啪精品午夜网站| 中文精品无码中文字幕无码专区| 99久久婷婷国产综合精品青草漫画 | 国产偷国产偷亚洲高清午夜| 69人妻精品中文字幕| 亚洲国产精品日韩在线| 国产精品天天狠天天看| 大肉大捧一进一出好爽视频mba| 女同在线观看亚洲国产精品| 国产桃色在线成免费视频| 翘臀少妇被扒开屁股日出水爆乳| 性视频一区| 欧美中文字幕无线码视频 | 少妇高潮喷水久久久影院| 国产人妻高清国产拍精品| 国产不卡的一区二区三区| 亚洲AV无码久久精品日韩| 国产区成人精品视频| 久久人人97超碰精品| 国产性三级高清在线观看| 又粗又硬又黄a级毛片| 国产人妻精品午夜福利免费 | 97人妻精品一区二区三区| 四川丰满少妇无套内谢| 九九热精品在线观看| 国产国语毛片在线看国产| 国产精品区一区第一页| 国产suv精品一区二区883|