selector汇编语言

汇编语言知多少(三): 函数调用

2018-10-25  本文已影响132人  Lin__Chuan

接着上一篇文章, 这篇主要讲汇编程序中函数的调用.

call 和 ret 指令: 函数的调用.

下面是代码的一部分, 功能是 调用 print '函数', 打印字符串

; 代码段
code segment
start:
    ; 手动设置ds, ss 的值
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax

    ; 业务逻辑
    call print
    
    ; 程序退出
    mov ah, 4ch
    int 21h

    ; 如果这里程序不退出, 它会继续向下执行 print 这个函数, 'print' 在这里只是相当于一个标志

print:
    ; ds: dx 告知字符串地址
    lea dx, string
    mov ah, 9h  ; 功能号 9h 指在屏幕上显示字符串
    int 21h     ; 执行 DOS 系统功能调用.
    ret

code ends 

end start 

我需要说明的几点

  1. call print, print 这里就是一个标号(函数名), call 将下一条指令的偏移地址入栈后, 转到 print 处执行指令, 这个 下一条指令 就是 mov ah, 4ch.
  2. 当 print 处的代码执行完后, 每个函数都会有一个 ret 指令, 这个指令会将栈顶的值出栈, 栈顶的值就是 mov ah, 4ch 这条指令的偏移地址, 赋值给 ip. 导致 print 函数执行完后, 可以继续向下执行其他的指令.

函数调用的整个流程

assume cs:code, ds:data, ss:stack

; 栈段
stack segment
    db 100 dup(0)
stack ends  

; 数据段
data segment  
    db 100 dup(0) 
data ends

; 代码段
code segment
start:
    ; 手动设置ds、ss的值
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax 
    
    mov si, 1
    mov di, 2
    mov bx, 3 
    mov bp, 4
    
    ; 业务逻辑
    push 1
    push 2 
    call sum 
    add sp, 4 
    
    ; 退出
    mov ax, 4c00h
    int 21h 
    
; 返回值放ax寄存器
; 传递2个参数(放入栈中)    
sum:
    ; 保护bp    
    push bp
    ; 保存sp之前的值:指向bp以前的值
    mov bp, sp
    ; 预留10个字节的空间给局部变量 
    sub sp, 10
    
    ; 保护可能会用到的寄存器
    push si
    push di
    push bx 
    
    ; 给局部变量空间填充int 3(CCCC)
    ; stosw的作用:将ax的值拷贝到es:di中,同时di的值会+2
    mov ax, 0cccch
    ; 让es等于ss
    mov bx, ss
    mov es, bx 
    ; 让di等于bp-10(局部变量地址最小的区域)
    mov di, bp
    sub di, 10   
    ; cx决定了stosw的执行次数
    mov cx, 5  
    rep stosw  
    ; rep的作用:重复执行某个指令(执行次数由cx决定)
     
    ; -------- 业务逻辑 - begin
    ; 定义2个局部变量
    mov word ptr ss:[bp-2], 3 
    mov word ptr ss:[bp-4], 4 
    mov ax, ss:[bp-2]
    add ax, ss:[bp-4]
    mov ss:[bp-6], ax 
    
    ; 访问栈中的参数
    mov ax, ss:[bp+4]
    add ax, ss:[bp+6] 
    add ax, ss:[bp-6]   
    ; -------- 业务逻辑 - end 
    
    ; 恢复寄存器的值
    pop bx
    pop di
    pop si
                       
    ; 恢复sp
    mov sp, bp
    ; 恢复bp
    pop bp
    
    ret 
                
code ends  

end start

说明

栈帧 (Stack Frame Layout)

栈帧是一个函数执行的环境, 包括参数, 局部变量, 返回地址

注意: 方向和上面是相反的.


上一篇 下一篇

猜你喜欢

热点阅读