1. 程式人生 > 實用技巧 >實驗4 彙編應用程式設計和c語言程式反彙編分析

實驗4 彙編應用程式設計和c語言程式反彙編分析

1. 實驗任務1

教材「實驗9 根據材料程式設計」(P187-189)

程式設計:在螢幕中間分別顯示綠色、綠底紅色、白底藍色的字串'welcome to masm!'。

程式碼:

assume cs:codesg, ds:datasg, ss:stacksg
  
datasg segment
        db 'welcome to masm!'
        db 2h,24h,71h                
datasg ends


stacksg segment stack
        db 16 dup (0)
stacksg ends

codesg segment

start:
        mov ax,datasg
        mov ds,ax

        mov ax,stacksg
        mov ss,ax
        mov sp,
16 mov ax,0B872h mov es,ax mov cx,3 mov bx,16 s: push cx mov cx,16 mov si,0 mov di,0 s0: mov al,ds:[di] mov ah,ds:[bx] mov es:[si],ax add si,
2 inc di loop s0 pop cx mov ax,es add ax,00ah mov es,ax inc bx loop s mov ax,4c00h int 21h codesg ends end start

結果:

實現思路:

首先計算輸出的行列位置。由於要在螢幕中間,因此行號為11,12,13行。根據表格可知,11行的起始地址為1760。列要從(160-32)/2=64開始,因此初始行列地址為1824,十六進位制為720h.

之後通過迴圈,便可以實現列印到螢幕上。內層迴圈控制列印字元,外層迴圈控制行數。

2. 實驗任務2

編寫子程式printStr,實現以指定顏色在螢幕上輸出字串。呼叫它,完成字串輸出。

程式碼:

assume cs:code, ds:data
data segment
    str db 'try', 0
data ends

code segment
start:  
    mov ax, data
    mov ds, ax

    mov si, offset str
    mov al, 2
    call printStr

    mov ah, 4ch
    int 21h

printStr:
    push bx
    push cx
    push si
    push di

    mov bx, 0b800H
    mov es, bx
    mov di, 0
s:      mov cl, [si]
    mov ch, 0
    jcxz over
    mov ch, al
    mov es:[di], cx
    inc si
    add di, 2
    jmp s

over:   pop di
    pop si
    pop cx
    pop bx
    ret

code ends
end start

結果:

對源程式做如下修改: 把line3改為:

str db 'another try', 0

把line12改為:

mov al, 4

得到的結果:

基於執行結果,理解原始碼,以及,組合使用轉移指令call和ret實現子程式的原理與方法。具體地,在

line18-40中:

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

  答:儲存子程式執行前各暫存器的值,在子程式執行完畢後,將各暫存器中的值恢復子程式執行前的狀態。

  line30的功能是什麼?

  答:將字元及其顏色屬性輸入到指定的視訊記憶體中,即列印到螢幕中。

3. 實驗任務3

使用任意文字編輯器,錄入彙編源程式task3.asm。

程式碼:

assume cs:code, ds:data
data segment
        x dw 1984
        str db 16 dup(0)
data ends

code segment
start:  
        mov ax, data
        mov ds, ax
        mov ax, x
        mov di, offset str
        call num2str

        mov ah, 4ch
        int 21h

num2str:
        push ax
        push bx
        push cx
        push dx
        
        mov cx, 0
        mov bl, 10
s1:      
        div bl
        inc cx
        mov dl, ah
        push dx
        mov ah, 0
        cmp al, 0
        jne s1
s2:        
        pop dx
        or dl, 30h
        mov [di], dl
        inc di
        loop s2
        
        pop dx
        pop cx
        pop bx
        pop ax

        ret
code ends
end start

閱讀原始碼,理解子程式num2str的彙編實現。

子任務1 對task3.asm進行彙編、連結,得到可執行程式後,在debug中使用u命令反彙編,使用g命令執行 到line15(程式退出之前),使用d命令檢視資料段內容,觀察是否把轉換後的數字字串'1984'存放 在資料段中str標號後面的單元。

子任務2 對task3.asm原始碼進行修改、完善,把task2.asm中用於輸出以0結尾的字串的子程式加進來, 實現對轉換後的字串進行輸出。

子任務1:

可見已將轉換後的字串存入了str的記憶體單元中

子任務2:

程式碼:


assume cs:code, ds:data


data segment


x dw 1984


str db 16 dup(0)


data ends



code segment


start:


mov ax, data


mov ds, ax


mov ax, x


mov di, offset str


mov si,0


call num2str



mov ah, 4ch


int 21h



num2str:


push ax


push bx


push cx


push dx



mov cx, 0


mov bl, 10




s1:


div bl


inc cx


mov dl, ah


push dx


mov ah, 0


cmp al, 0


jne s1


s2:


pop dx


or dl, 30h


mov [di], dl


mov dh,2


mov ax,0b800h


mov es,ax


mov es:[si],dx


add si,2


inc di


loop s2



pop dx


pop cx


pop bx


pop ax



ret


code ends


end start

截圖:

將line3的數值改成 2000後,得到結果如下:

4. 實驗任務4

使用任意文字編輯器,錄入彙編源程式task4.asm。

程式碼:
assume cs:code, ds:data
data segment
        str db 80 dup(?)
data ends

code segment
start:  
        mov ax, data
        mov ds, ax
        mov si, 0

s1:        
        mov ah, 1
        int 21h
        mov [si], al
        cmp al, '#'
        je next
        inc si
        jmp s1
next:
        mov cx, si
        mov si, 0
s2:     mov ah, 2
        mov dl, [si]
        int 21h
        inc si
        loop s2

        mov ah, 4ch
        int 21h
code ends
end start

輸入2020,bye# 得到結果如下:

彙編、連結、執行程式,輸入一個字串並以#結束(比如,2020, bye#)觀察執行結果。結合執行結 果,理解程式功能,瞭解軟中斷指令。 具體地:   line12-19實現的功能是?   答:利用軟中斷指令,利用int21h的1號子功能,若當前輸入的字元不是'#',將從鍵盤輸入的字元存到指定的棧段中。   line21-27實現的功能是?   答:向標準輸出裝置(如螢幕)輸出棧段中的內容。 5. 實驗任務5 在visual studio整合環境中,編寫一個簡單的包含有函式呼叫的c程式。 程式碼如下:
#include <stdio.h>
int sum(int, int);
int main() {
int a = 2, b = 7, c;
c = sum(a, b);
return 0;
}
int sum(int x, int y) {
return (x + y);
}

在line7, line13分別設定斷點,在除錯模式下,檢視反彙編程式碼。 分析反彙編程式碼,從彙編的角度,觀察高階語言中引數傳遞和返回值是通過什麼實現的,以及,引數入 棧順序,返回值的帶回方式,等等。

截圖: 分析: 通過反彙編程式碼可以看出,高階語言的引數傳遞是通過暫存器實現的。引數的入棧方式是從左到右,int型別的返回值是從eax返回的。