转载地址: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 }

                

汇编语言笔记 CALL和RET指令的更多相关文章

  1. 汇编语言---call和ret指令

    汇编语言--call和ret指令 call和ret指令 call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP. 它们经常被共同用来实现子程序的设计. ret和retf ret指令用栈 ...

  2. 汇编学习笔记(7)call和ret指令

    ret和retf CPU执行ret指令时进行以下两步操作: (IP)=((ss)*16+(sp)) (sp)=(sp)+2 这相当于pop IP CPU执行retf指令时进行以下四步操作: (IP)= ...

  3. [汇编学习笔记][第十章 CALL和RET指令]

    第十章 CALL和RET指令 call和ret指令都是转移指令,它们都修改CS和IP.经常被共同用于实现子程序的设计.这一章,我们讲解call和ret指令的原理 10.1 ret和retf ret指令 ...

  4. 王爽汇编第十章,call和ret指令

    目录 王爽汇编第十章,call和ret指令 call和ret指令概述: ret和retf ret指令 retf指令 call 和 ret 的配合使用 call指令详解 call原理 call指令所有写 ...

  5. call 和 ret 指令

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  6. 汇编-10.0-CALL和RET指令

    call和ret指令都是转移指令,他们都是修改IP,或同时修改CS和IP.它们常被共同用来实现子程序设计. 1.ret和retf ret指令用栈中的数据,修改IP的内容,从而实现近转移: retf指令 ...

  7. angular学习笔记(6)- 指令

    angular1学习笔记(6)- 指令 restrict-匹配模式 1.A - 属性 <my-menu title=Products></my-menu> 2.M - 注释 & ...

  8. 第十章 Call 和 Ret 指令

    引言 想想程序之间的加载返回过程. call 和 ret 指令都是转移指令,它们都修改 IP,或同时修改 CS 和 IP. call 和 ret 经常被共同用来实现自程序的设计. 这一章,我们讲解 c ...

  9. 自己总结:汇编CALL和RET指令

    ret指令,相当于 pop IP:修改IP的内容,从而实现近转移 retf指令,相当于 pop IP pop CS:修改CS和IP的内容,从而实现远转移 -------------- CPU执行cal ...

随机推荐

  1. git clone一个仓库下的单个文件【记录】

    注意:本方法会下载整个项目,但是,最后出现在本地项目文件下里只有需要的那个文件夹存在.类似先下载,再过滤. 有时候因为需要我们只想gitclone 下仓库的单个或多个文件夹,而不是全部的仓库内容,这样 ...

  2. 正则表达式"(^|&)" ,什么意思?

    ^匹配字符串开头,&就是&字符 (^|&)匹配字符串开头或者&字符,如果其后还有正则,那么必须出现在字符串开始或&字符之后 用法一:   限定开头 文档上给出了 ...

  3. Java8 基础数据类型包装类-Long

     https://blog.csdn.net/u012562117/article/details/79023440 基础 //final修饰不可更改,每次赋值都是新建类(其中-128~127是通过L ...

  4. Java Web 深入分析(12) JVM(2) 垃圾收集与内存分配

    前言 java的内存分配和垃圾回收往往是影响系统性能和并发能力的主要因素,虚拟机提供许多的参数就是为了根据不同环境和请教下进行调优,没有最好的调优也没有固定的调优.需要我们深入的去了解jvm的各个垃圾 ...

  5. bat计算指定文件MD5并输出txt

    @echo off set Name1=*.ADS set Name2=GM_RSSPI* set Name3=equipment* set Name4=protocols* REM 设置输出文件名 ...

  6. HelloWorld! C++纠错版

    例题:1 #include<iostream> int main() { cout << "HelloWorel!" ; ; } #include < ...

  7. HTML Marquee跑马灯

    Marquee是html的标签,所有的主流浏览器都能兼容,用于创建文字滚动. 来介绍下标签的属性 滚动方向 direction <!--滚动方向 direction 4个值 up down le ...

  8. php ajax生成excel并下载

    目标:使用php,通过ajax请求的方式生成一个excel,然后下载. 思路:大致思路是发送一个ajax请求到后台,后台php处理后生成一个excel文件,然后把生成的文件放到一个临时目录,然后把文件 ...

  9. DDL 操作表结构

    DDL 操作表结构:CRUD 一.C(create)创建 1.创建表 create table 表名( 列名1 数据类型1, 列名2 数据类型2, 列名3 数据类型3, ... 列名n 数据类型n ) ...

  10. aapt&adb笔记

    aapt 查看安装包信息aapt list apk路径* aapt list xxx/app-debug.apk 查看apk文件信息并保存到本地(> 重定向符) * aapt list xx/a ...