汇编-8086 栈平衡,call和ret使用

2020-03-25  本文已影响0人  梦醒了i77

先上代码

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

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

:数据段
data segment 
   db 100 dup(0)
   string db 'Hello!$'
data ends

:代码段
code segment 

start:
         
    mov ax, data
    mov dx, ax
    mov ax, stack
    mov ss, ax      
    
    :调用函数   
    push word ptr offset string    
    call print
    add sp, 2    
    
    push 1111h
    push 2222h
    call count
    add sp, 4
    push ax  
    call print
    add sp, 2

    

    
    mov ax, 4c00h
    int 21h    
    
count:         

    mov bp, sp

    mov ax, ss:[bp+2]
    mov bx, ss:[bp+4]
    add ax, bx
    ret    
    
print:
    mov bp, sp
    mov dx, ss:[bp+2]
    mov ah, 9h
    int 21h
    ret 
             
code ends 

end start

开始分析

push word ptr offset string 

将在数据段中的字符串Hello!的位置push到栈中($:代表结束,offset在数据段的偏移量

call print

会转到print
同时会把下一条指令的偏移地址push到栈中

bp为基址寄存器,一般在函数中用来保存进入函数时的sp的栈顶基址

sp是栈顶指针,它每次指向栈顶。

mov bp, sp

mov ax, ss:[bp+2]
mov bx, ss:[bp+4]
add ax, bx

ret

然后 ret会将ip指向到栈顶,也就是call push进来的偏移地址(ip就是下一条处理的地址

默认做法返回值会赋值给ax

为了保证栈平衡,调用完一个函数之后sp会加传进去的参数长度

也就是将栈顶恢复到调用这个方法之前的位置

1585038202(1).png
上一篇下一篇

猜你喜欢

热点阅读