汇编入门学习笔记 (九)—— call和ret

发布者:CuriousMind123最新更新时间:2016-06-24 来源: eefocus关键字:汇编入门  call  ret 手机看文章 扫描二维码
随时随地手机看文章
疯狂的暑假学习之  汇编入门学习笔记 (九)——  call和ret

 

参考: 《汇编语言》 王爽 第10章

 

call和ret都是转移指令。

 

1. ret和retf

 

ret指令:用栈中的数据,修改IP内容,从而实现近转移

相当于:

pop ip

retf指令:用栈中的数据,修改CS和IP,从而实现远转移

相当于:

 

pop ip

 

 

pop cs

 

 

例子:ret

 

  1. assume cs:code,ss:stack  
  2.   
  3. stack segment  
  4.     db 16 dup(1)  
  5. stack ends  
  6.   
  7. code segment  
  8.     mov ax,4c00H  
  9.     int 21H  
  10.   
  11. start:  mov ax,stack  
  12.     mov ss,ax  
  13.     mov sp,16  
  14.       
  15.     mov ax,0  
  16.     push ax  
  17.     ret  
  18.       
  19. code ends  
  20.   
  21. end start  

 

retf

 

  1. assume cs:code,ss:stack  
  2.   
  3. stack segment  
  4.     db 16 dup(1)  
  5. stack ends  
  6.   
  7. code segment  
  8.     mov ax,4c00H  
  9.     int 21H  
  10.   
  11. start:  mov ax,stack  
  12.     mov ss,ax  
  13.     mov sp,16  
  14.       
  15.     mov ax,0  
  16.     push cs  
  17.     push ax  
  18.           
  19.     retf  
  20.       
  21. code ends  
  22.   
  23. end start  


 

2. call指令

 

call指令,执行操作:

    1.将当前IP或CS和IP压入栈中

    2.跳转

 

(1)依据位移进行转移的call指令

 

 

格式: call 标号

 

将下一条的指令的ip压入栈中,在转到标号处

 

相当于:

 

push ip

jmp near ptr 标号

 

 

 

(2)转移的目的地址在指令中的call指令

 

格式:

call far ptr 标号

 

将下一条的指令的CS和IP压入栈中,在转到标号处

 

相当于:

push cs

push ip

jmp far ptr

 

(3)转移地址地址在寄存器中的call指令

 

格式:call 16位reg

 

相当于:

push ip

jmp 16位reg

 

(4)转移地址在内存中的call指令

   1. call word ptr 内存单元

        相当于:

             push ip

             jmp word ptr 内存单元

   2. call dword ptr 内存单元

        相当于:

              push cs

              push ip

              jmp dword ptr 内存单元

 

3. mul 指令

 

mul 是乘法指令

 

表示两个数相乘,它必须是都是8位或者都是16位

 

8位相乘 结果默认存放在ax中

16位相乘 结果高位存放在dx中,低位存放在ax中

例子见下面。

 

 

3. call和ret配合使用

 

call于ret结合使用,就相当于函数。

 

例子:求dw中数值的3次方。把bx当做“函数”参数,ax当做“函数”的返回值。

 

  1. assume cs:code,ds:data  
  2.   
  3. data segment  
  4.     dw 1,2,3,4,5,6,7,8  
  5.     dd 0,0,0,0,0,0,0,0  
  6. data ends  
  7.   
  8. code segment  
  9.     start:  mov ax,data  
  10.         mov ds,ax  
  11.           
  12.         mov si,0  
  13.         mov di,16  
  14.         mov cx,8  
  15.     s:  mov bx,ds:[si]  
  16.         call cube  
  17.         mov ds:[di],ax  
  18.         mov ds:[di+2],dx  
  19.           
  20.         add si,2  
  21.         add di,4  
  22.         loop s  
  23.               
  24.         mov ax,4c00H  
  25.         int 21H  
  26.               
  27.               
  28.     cube:   mov ax,bx  
  29.         mul bx  
  30.         mul bx  
  31.         ret  
  32.               
  33.                   
  34. code ends  
  35.   
  36. end start  

 

寄存器数量有限,如果要传的参数,或者返回的参数过多。可以使用内存,或者栈。

 

例子:小写转大写。(用内存存放参数)

 

  1. assume cs:code,ds:data  
  2.   
  3. data segment  
  4.     db 'conversation'  
  5. data ends  
  6.   
  7. code segment  
  8.     start:  mov ax,data  
  9.         mov ds,ax  
  10.           
  11.         mov si,0  
  12.         mov cx,12  
  13.         call captial  
  14.           
  15.         mov ax,4c00H  
  16.         int 21H  
  17.               
  18. captial:and byte ptr ds:[si],11011111b  
  19.         inc si  
  20.         loop captial  
  21.               
  22. code ends  
  23.   
  24. end start  

 

例子:计算 (a - b) ^3  假设a=3,b=1 (用栈来存放参数)

 

  1. assume cs:code  
  2.   
  3. code segment  
  4.     start:  mov ax,1  
  5.         push ax  
  6.         mov ax,3  
  7.         push ax  
  8.         call difcube  
  9.           
  10.         mov ax,4c00H  
  11.         int 21H  
  12.           
  13. difcube:push bp  
  14.         mov bp,sp  
  15.         mov ax,[bp+4]  
  16.         sub ax,[bp+6]  
  17.         mov bp,ax  
  18.         mul bp  
  19.         mul bp  
  20.         pop bp  
  21.           
  22.         ret 4  
  23. code ends  
  24.   
  25. end start  

 

上面代码中的 ret 4 表示:

pop ip

add sp,n

例子:小写转大写,用0结尾来判断。(用栈来处理寄存器冲突)

 

  1. assume cs:code,ds:data  
  2.   
  3. data segment  
  4.     db 'word',0  
  5.     db 'city',0  
  6.     db 'good',0  
  7. data ends  
  8.   
  9. code segment  
  10.     start:  mov ax,data  
  11.         mov ds,ax  
  12.         mov cx,3  
  13.           
  14.         mov bx,0  
  15.     s:  push cx  
  16.         mov si,bx  
  17.         call capital  
  18.         add bx,5  
  19.         pop cx  
  20.         loop s  
  21.               
  22.         mov ax,4c00H  
  23.         int 21H  
  24.               
  25. capital:mov cl,[si]  
  26.         mov ch,0  
  27.         jcxz ok  
  28.         and byte ptr [si],11011111b  
  29.         inc si  
  30.         jmp short capital  
  31.         ok: ret       
  32. code ends  
  33.   
  34. end start  

注意:要用栈保存cx

 

例子:实现show_str “函数”  在屏幕显示字符串。用dh指定函数 ,dl指定列号,cl指定颜色

 

  1. assume cs:code,ds:data,ss:stack  
  2.   
  3. data segment  
  4.     db 'Welcome to masm!',0  
  5. data ends  
  6.   
  7. stack segment  
  8.     dw 8 dup(0)  
  9. stack ends  
  10.   
  11. code segment  
  12.     start:  mov ax,data  
  13.         mov ds,ax  
  14.         mov ax,stack  
  15.         mov ss,ax  
  16.         mov sp,16  
  17.           
  18.         mov dh,10  ;行  
  19.         mov dl,17  ;列  
  20.         mov cl,2   ;颜色  
  21.         mov si,0  
  22.         call show_str  
  23.               
  24.         mov ax,4c00h  
  25.         int 21h  
  26.           
  27. show_str:   push ax  
  28.         push di  
  29.         push dx  
  30.               
  31.         mov ax,10   ;确定行段 es  
  32.         mul dh  
  33.         add ax,0b800h  
  34.         mov es,ax  
  35.           
  36.         mov dh,0    ;确定列偏移 di,注意,一个字符两个字节  
  37.         add dx,dx  
  38.         mov di,dx  
  39.               
  40.               
  41.     s:  push cx    ;保存cx  
  42.               
  43.         mov ch,0  
  44.         mov cl,ds:[si]  
  45.         jcxz ok      ;如果为0 跳转  
  46.           
  47.         mov es:[di],cl  
  48.         pop cx  
  49.         mov es:[di+1],cl  
  50.           
  51.         inc si  
  52.         add di,2  
  53.         jmp short s  
  54.               
  55.               
  56.               
  57.     ok: pop cx    ;不要忘记pop,眼不让rec还原的ip就不对了  
  58.         pop dx  
  59.         pop di  
  60.         pop ax  
  61.         ret  
  62.               
  63.   
  64. code ends  
  65.   
  66. end start  

关键字:汇编入门  call  ret 引用地址:汇编入门学习笔记 (九)—— call和ret

上一篇:汇编入门学习笔记 (十)—— 标志寄存器、串传送指令
下一篇:汇编入门学习笔记 (八)—— 转移指令

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved