zoukankan      html  css  js  c++  java
  • 汇编语言笔记 CALL和RET指令

    转载地址:http://www.cnblogs.com/dennisOne

    ☞模块化程序设计

    1. 模块化程序设计

      汇编语言通过call和ret指令实现了模块化程序设计。可以实现多个相互联系、功能独立的子程序来解决一个复杂的问题。

    2. 子程序的框架
      复制代码
       1 assume cs:code
       2 code segment
       3     main:     :
       4               :
       5               call sub1          ; 调用子程序sub1
       6               :
       7               :
       8               mov ax, 4c00h
       9               int 21h
      10     
      11     sub1:     :                  ; 子程序sub1开始
      12               :
      13               call sub2          ; 调用子程序sub2
      14               :
      15               :
      16               ret                ; 子程序返回
      17      
      18     sub2:     :                  ; 子程序sub2开始
      19               :
      20               :
      21               ret                ; 子程序返回
      22 code ends
      23 end main
      复制代码

    ☞call和ret指令

    指令

    功能

    汇编语法解释

    备注

    ret

    用栈中的数据,修改IP的内容,

    实现近转移。

    pop IP

      

    retf

    用栈中的数据,修改CS和IP的内容,

    实现远转移。

    pop IP

    pop CS

      

    retn

      

    pop IP

    add sp, n

    见后面

       

       

       

       

       

    call

       

       

       

       

    call指令分为两步:

    (1) 将当前的IP或者CS和IP压入栈中。

    (2) 转移。

    格式

    汇编语法解释

    call 标号

    push IP

    jmp near ptr 标号

    call far 标号

    push CS

    push IP

    jmp far ptr 标号

    call 16位reg

    push IP
    jmp 16位reg

    call word ptr 内存单元地址

    push IP
    jmp word ptr 内存单元地址

    call dword ptr 内存单元地址

    push CS
    push IP
    jmp dword ptr 内存单元地址

       

       

       

    call

       

    ☞mul和div指令

    指令格式

    解释

    示例


    mul reg

    mul 内存单元

    (1) 8位乘法:默认乘子一个放在AL中,另一个放在8位reg或者内存字节单元中。默认结果放在AX中

    (2)16位乘法:默认乘子一个放在AX中,另一个放在16位reg或者内存字单元中。默认结果放在DX|AX中。

    mul byte ptr ds:[0]

    ; (ax)=(al)*((ds)*16+0)

       

    mul word ptr [bx+si+8]

    ; (dx|ax)=(ax)*((ds)*16+(bx)+(si)+8)

    div reg

    div 内存单元

    (1)16位/8位: 被除数默认放在AX中,除数放在8位reg或者内存字节单元中。结果AL(商),AH(余数)。

    (2)32位/16位: 被除数默认DX|AX中,除数放在16位reg或者内存字单元中。结果AX(商), DX(余数)。

    (3)会产生越界问题(如何设计安全的div见后面)

    div byte ptr ds:[0]
    ; (al) = (ax)/((ds)*16+0)的商
    ; (ah) = (ax)/((ds)*16+0)的余数

    div word ptr [bx+si+8]

    ; (ax)=(ax)/((ds)*16+(bx)+(si)+8)的商

    ; (dx)=(ax)/((ds)*16+(bx)+(si)+8)的余数

       

    ☞参数和结果传递

    位置

    优点

    缺点

    示例

       

       

       

    放在寄存器中

       

       

       

    最常见的方法

    快速

       

       

       

    寄存器数量有限,

    寄存器可能会冲突

    ; 说明:计算N的3次方

    ; 参数: (bx)=N

    ; 结果: (dx:ax)=N^3

    cube:        mov ax, bx

    mul bx

    mul bx

    ret

    放在数据段中

    批量数据的传递

    速度慢

    ; ds:si指向字符串(批量数据)所在空间的首地址

    ; cx存放字符串的长度

    capital:        and byte ptr [si], 11011111b

    inc si

    loop capital

    ret

    放在栈中

    C语言的方式

    简单方便

      

    详细解释

       

    • 附1:用栈传递参数

      结合C语言的函数调用来学习栈传递参数的思想。

      复制代码
       1 ; 说明:计算(a-b)^3,a、b为字型数据
       2 ; 参数:进入子程序时候,栈顶存放IP,后面依次存放a、b
       3 ; 结果:(dx:ax)=(a-b)^3
       4 difcube:    push bp
       5              mov bp, sp
       6              mov ax, [bp+4]     ;将栈中a的值送入ax中
       7              sub ax, [bp+6]     ; a-b
       8              mov bp, ax
       9              mul bp
      10              mul bp
      11              pop bp
      12              ret 4              ; 弹出参数(将栈顶指针修改为调用前的值)
      13     
      14 ;指令ret n的含义:
      15 ;    pop ip
      16 ;    add sp,n 
      复制代码

      使用栈进行参数传递,所以调用者在汇编程序的时候要向栈中压入参数,子程序在返回的时候可以使用ret n指令将栈顶指针修改为调用前的值。

    • 附2: C语言处理方式(局部变量,也是使用栈)
      复制代码
       1 void add(int, int, int);
       2     
       3 void main()
       4 {
       5     int a = 1;
       6     int b = 2;
       7     int c = 0;
       8     add(a, b, c);
       9     c++; 
      10 }
      11     
      12 void add(int a, int b, int c)
      13 {
      14      c = a + b;
      15 }
      复制代码

                  

  • 相关阅读:
    VC++读写文件
    VC++编译说明
    VC++时间函数总结
    VC++多工程项目
    VC++全局变量初始化
    Linux 系统免密码登陆远程服务器
    debian 系统安装配置apache
    数据库授权
    Mysql 主从服务器数据同步
    centos Install Docker
  • 原文地址:https://www.cnblogs.com/LittleRedPoint/p/4009115.html
Copyright © 2011-2022 走看看