彙編語言--如何調用子程序

  彙編語言的程序調用:

1:程序內部標號調用

我們來看一個例子:編制一個子程序,求y=x^4,x爲字節,y爲字,且不會溢出。

1.1:子程序的參數由寄存器bl提供,返回結果在ax中。
  實現如下:
  
assume cs:codesg, ss:stack
stack segment
    db  32 dup (0)
stack ends
codesg segment
main proc
start: mov ax,stack
       mov ss,ax
       mov sp,16
       mov bl,08  ;爲調用子程序準備參數
       call subp
       ;子程序調用返回後要做的處理
       mov ax,4c00h
       int 21h
main endp
;強調:從現在始,定義子程序必須要有這樣的文檔
;子程序功能:求y=x^4
;入口參數:x的值由bl提供
;返回值:y值由ax返回,且y值不會超過1個字的範圍
subp proc
    push cx;子程序中使用的寄存器入棧
    mov bh,0;子程序內容
    mov dx,0
    mov ax,0
    mov al,bl
    mov cx,3
 s: mul bx
    loop s
    pop cx;子程序使用的寄存器出棧
    ret
subp endp
codesg ends
end start

解析:這個比較簡單就不多講了,看下面的。
1.2:程序不變,主程序中提供如下數據區
data segment
 x db 1,2,3,4,5,6,7,8
 y dw 0,0,0,0,0,0,0,0
data ends
子程序完成全部8個數據的求解任務,主程序只調用一次子程序即可。
這個怎麼實現?

assume cs:codesg,ss:stack,ds:data
data segment 
     x db 1,2,3,4,5,6,7,8
     y dw 0,0,0,0,0,0,0,0
data ends
stack segment
    db  32 dup (0)
stack ends
codesg segment
main proc
start: mov ax,stack
       mov ss,ax
       mov ax,data
       mov ds,ax
       mov sp,16
       mov si,0;
       mov di,8 ;爲調用子程序準備參數
       call subp
       mov ax,4c00h  ;子程序調用返回後要做的處理
       int 21h
main endp
;子程序功能:求y=x^4
;入口參數:x的值由bl提供
;返回值:y值由ax返回,且y值不會超過1個字的範圍
subp proc
    push cx;子程序中使用的寄存器入棧
    push bx
    mov bx,0;子程序內容
    mov cx,8
s1: push cx
    mov dx,0
    mov ax,0
    mov bl,byte ptr [si]
    mov al,bl
    mov cx,3
 s: mul bx
    loop s
    pop cx;子程序使用的寄存器出棧
    mov word ptr [di],ax
    add di,2
    inc si
    loop s1
   pop cx
   pop bx
   ret
subp endp
codesg ends
end start

解析:主程序只是給出了地址的偏移量。我們要在子程序中實現。首先將要用到的寄存器的值保護起來,入棧,然後使用寄存器
、幹我們想幹的事(畢竟寄存器在還是稀缺資源)。構建雙重循環,一層實現數的遍歷,一層要來求數的四次方,每次求完一個數,根據di將其寫回內存中去。大體思路就是這樣。

2:程序外部如何調用?

要求:將上面的程序2按多文件的方式存放。
代碼實現:
子程序:


;子程序功能:求內存中偏移量爲si的連續八個數的4次方
;然後將結果放在後面,每個結果數佔用一個字
;入口參數:si di,si數的來源偏移量,di結果放置的偏移量
;返回值:返回 8個數的4次方,放在di指定的內存中masm
public subp
assume cs:code
code segment
start:
subp proc
    push cx;子程序中使用的寄存器入棧
    mov bx,0;子程序內容
    mov cx,8;外層循環八次
s1: push cx;外層循環量入棧
    mov dx,0
    mov ax,0;初始化將要用的寄存器
    mov bl,byte ptr [si];從內存取出數
    mov al,bl;放入ax,再連乘3次就是bl的4次方
    mov cx,3
 s: mul bx
    loop s
    pop cx;子程序使用的寄存器出棧
    mov word ptr [di],ax
    add di,2
    inc si
    loop s1
   pop cx;恢復,原來cx的值
   ret
subp endp
code ends
end start


主程序:

extrn subp :far
assume cs:codesg,ss:stack,ds:data
data segment 
     x db 1,2,3,4,5,6,7,8
     y dw 0,0,0,0,0,0,0,0
data ends
stack segment
    db  32 dup (0)
stack ends
codesg segment
main proc
start: mov ax,stack
       mov ss,ax
       mov ax,data
       mov ds,ax
       mov sp,16
       mov si,0;
       mov di,8 ;爲調用子程序準備參數
       call far ptr subp
       mov ax,4c00h  ;子程序調用返回後要做的處理
       int 21h
main endp
codesg ends
end start


解釋:首先在子程序中有 public subp,表示程序中標號爲subp的地方爲公有的,類似於c++和java,其他程序可以調用。
在主程序中有個 extrn subp:far,表示本程序要用到一個外部程序,入口地址在標號爲subp處,經遠轉移可到達。
編譯的時候兩個文件單獨編譯,link的時候 要 link 1.obj+2.obj 將兩個文件link在一起,執行的時候只需執行1.exe。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章