美文网首页
5.call和ret指令

5.call和ret指令

作者: 芝麻酱的简书 | 来源:发表于2018-08-02 10:58 被阅读17次
屏幕快照 2018-08-02 10.57.29.png
call和ret指令使用:
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:
    ; 手动设置ds、ss的值
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax  
    
    ; 业务逻辑 
    call print
    
    mov ax, 1122h
    mov bx, 3344h
    add ax, bx  
    
    ; 退出
    mov ax, 4c00h
    int 21h 
    
; 打印字符串    
print:    

    ; ds:dx告知字符串地址    
    mov dx, offset string
    mov ah, 9h
    int 21h
    
    ret 
                
code ends  

end start 

; 函数的要素
; 1.参数
; 2.返回值
; 3.局部变量

实现函数返回值:

demo1:使用ds

assume cs:code ,ds:data ss:stack
data segment
  db 100 dup(0)
data ends

code segment
start:
      mov ax,data
      mov ds,ax
      call  returnFunc
      mov bx,[0]

returnFunc :
      mov ax,2
      add ax,ax
      mov [0],ax
      ret
code ends
end start

demo2:使用ds中的别名

...
data segment
   ;定义别名result
   result dw 0
data ends
...
start:
      mov ax,data
      mov ds,ax
      call  returnFunc
      mov bx,result
...
returnFunc :
      mov ax,2
      add ax,ax
      mov result,ax
      ret

demo3:通用做法是返回值直接放在ax通用寄存器中


实现函数传参:

1.使用ax寄存器存储参数来实现传递
2.使用栈来存储参数来传递,也是通用做法:

  • 使用bp来快速访问栈中数据
  • 使用mov sp指令来快速释放栈中数据
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  
    
    ; 业务逻辑
    push 1122h
    push 3344h 
    call sum3 
    add sp, 4
    
    push 2222h
    push 2222h 
    call sum3
    add sp, 4
        
    ; 退出
    mov ax, 4c00h
    int 21h 
    
; 返回值放ax寄存器
; 传递2个参数(放入栈中)    
sum3:   
    ; 访问栈中的参数
    mov bp, sp
    mov ax, ss:[bp+2]
    add ax, ss:[bp+4]
    ret 
          
; 返回值放ax寄存器
; 传递2个参数(分别放ds:0、ds:2)    
sum2:         
    mov ax, [0]
    add ax, [2]
    ret 
            
; 返回值放ax寄存器
; 传递2个参数(分别放cx、dx中)    
sum1:  
    mov ax, cx
    add ax, dx
    ret 
                
code ends  
end start
; 栈平衡:函数调用前后的栈顶指针要一致
; 栈如果不平衡的结果:栈空间迟早会被用完

注意区分递归调用、函数内调用函数和连续调用多个函数对栈的使用的区别,
函数内调用函数会一直往栈中压数据,而多函数连续调用,只会当前函数栈中数据释放后再继续下一个函数的压栈操作。


栈平衡的方法:

1.外平栈,函数外面进行平栈,也就是上面的操作,要是常用的做法
2.内平栈,函数内进行平栈,函数内调用其他函数的时候:

sum2:         
    mov ax, [0]
    add ax, [2]
    call sum1
    ret 
 
sum1:  
    mov ax, cx
    add ax, dx
    ret 4

相关文章

  • 5.call和ret指令

    call和ret指令使用: 实现函数返回值: demo1:使用ds demo2:使用ds中的别名 demo3:通用...

  • 汇编学习笔记(四)

    call和ret指令 call和ret都是转移指令,都修改IP,或同时修改CS和IP。 ret和retf ret ...

  • 子程序

    子程序设计 一、RET和RETF指令 1.RET指令 CPU执行ret指令时进行以下操作:IP = SS:[SP]...

  • 逆向 - 汇编 - 第四天

    Call 指令和 ret 指令 Call 指令:将下一条指令的偏移地址入栈;跳转到定位的地址, 执行指令; ret...

  • 学习汇编--写一个完整的汇编(二)

    call指令和ret指令 call 标号 执行方式将吓一条指令的地址入栈跳转到定位的地址执行指令 ret 将栈顶的...

  • call和ret

    call指令和ret指令 call 标号:将下一条指令的偏移地址入栈后转到标号处执行指令 ret:将栈顶的值出栈,...

  • call和ret指令

    1.call和ret指令都是转移指令,它们都修改IP的值,或同时修改CS和IP的值。它们经常共同用语实现子程序的设...

  • 8086汇编(17)call和ret

    call和ret指令 1、call标号 将下一条指令的偏移地址入栈后 转到标号处执行指令 2、 ret将栈顶的值出...

  • 汇编学习10 CALL与RET指令

    一、RET和RETF这两个指令都是转移指令,转移指令都是通过修改CS或者IP实现的跳转, 这两者也不例外。 RET...

  • 8086汇编(25)ret和retf

    ret和retf ret指令用栈中的数据,修改IP的内容,从而实现近转移; retf指令用栈中的数据,修改CS和I...

网友评论

      本文标题:5.call和ret指令

      本文链接:https://www.haomeiwen.com/subject/akdjvftx.html