王爽汇编第十章,call和ret指令
王爽汇编第十章,call和ret指令
call和ret指令概述:
call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP。他们经常被用来实现子程序(函数)的设计。
ret和retf
ret指令
ret指令:用栈中的数据,修改IP的内容,从而实现(近转移);
CPU执行ret指令时,需要进行下面两个步骤:
相当于:pop IP
- (1) (IP) = ((ss)*16+(sp))
- (2) (SP)=(sp)+2
retf指令
retf指令:用栈中的数据,修改CS和IP的内容,从而实现(``远转移`)。
CPU执行retf指令时,需要进行下面四个步骤
相当于:pop CS,pop IP
- (1) (IP) = ((ss)*16+(sp))
- (2) (SP) = (sp)+2
- (3) (CS) = ((ss)*16+(sp))
- (4) (SP) = (sp)+2
;************************************
; ret指令实验 *
;************************************
assume cs:code,ss:stack
;>>>>>>>>>>>>>>>>>>>>>
;堆栈段
;>>>>>>>>>>>>>>>>>>>>>
stack segment
db 16 dup(0)
stack ends
;>>>>>>>>>>>>>>>>>>>>>
;代码段
;>>>>>>>>>>>>>>>>>>>>>
code segment
mov ax,4c00h
int 21h;退出到DOS
main:;程序入口
mov ax,stack
mov ss,ax ;关联堆栈段
mov sp,16 ;设置栈顶
mov ax,0
push ax ;压栈
ret ;pop ip, ->cs:ip cs:0 ,让程序跳到入口处上面
code ends
end main
call 和 ret 的配合使用
call 与 ret 指令共同支持了汇编语言编程中的模块化设计

call指令详解
在X86架构下:call基本都是调用一个函数,比如调用MessageBox,在汇编中就会写成Call MessageBox,并且call经常和ret搭配使用,下面我们来说说call的原理。
call原理
CPU执行call指令时,会进行如下两个步骤:
- (1) 将当前的IP或者CS:IP压入栈中;
- (2) 转移指令(jmp)
我们这里先来看看x86架构下EXE执行call的流程。
用
x32dbg打开HelloWorld.exe,然后反汇编视图如下:此时我们还没执行Call,然后我们先记一下Call下条指令的地址
0x0040107C,然后接着第2步骤按F7进入到call内部,然后此时注意观察堆栈的信息。

我们按
F7进入到call内容。第一步里面我们记下来的
0x0040107C地址,被push到了堆栈里面,并且jmp到了函数的地址00401000,所以验证了之前CPU执行call指令会有两个步骤(push ip,并且jmp 到call 函数的地址)。

call指令所有写法
8086CPU架构中:
- call 标号(近转移)
push ip
jmp near ptr 标号
- call far ptr 标号(段间转移)
push cs
push ip
jmp fat ptr 标号
- call 16位寄存器
push ip
jmp ax
- call word ptr 内存单元地址
mov ax, 0123h
mov ds:[0],ax
call word ptr ds:[0]
;等于
push ip
jmp word ptr ds:[0]
- call dword ptr 内存单元地址
mov ds:[0],ax
mov word ptr ds:[2],0
call dword ptr ds:[0]
;等于 cs:ip 0:0123h
push cs
push ip
jmp dword ptr ds:[0]
X86CPU架构中:
先来看一张Intel X86架构手册的图片。

- E8 cw(w表示word的意思|代表后面要跟两个字节) - 近转移 位移
!注意! CPU在实模式下,0xE8才接受2字节操作数
0xE8 0x04 0x00 call 标号 偏移:0x04
- E8 cd(d表示dword的意思)
在保护式下,0xE8接受4字节操作数
0xE8 0x04 0x03 0x02 0x01 call 偏移:0x01234
- FF /2 (r/m32)
FF /2,是 0xFF 后面跟着一个 /digit 表示的东西。如下图 2 对应的就是DL带头的那一列,标红的这32个值代表了32种寻址方式。

;call的是取寄存器地址的值
FF 10 call dword ptr [eax]
FF 11 call dword ptr [ecx]
FF 12 call dword ptr [edx]
FF 13 call dword ptr [ebx]
;call的是寄存器的值
FF D0 call eax
FF D1 call ecx
FF D2 call edx
FF D3 call ebx

FF 15 [地址] 常见于调用Windows的导出表比如:
call dword ptr ds:[<&CreateFileA>]

- FF /2 (r/m64)
同32位,只是寄存器和地址都是64位的
- 9A cd(d表示dword的意思) -- call far ptr 标号(段间转移)
类似8086中的call far ptr
9A xx xx xx xx xx xx
其中最后两个xx xx = 段地址
9A后面4个xx = 要call的地址
push cs
push eip
jmp xx xx xx xx
执行call far ptr 标号前的数据

跟入call后的数据,注意堆栈的内容。

执行ret后

返回到了call调用处

call 指令大全图表
表格
| 指令 | 二进制格式 |
|---|---|
| call rel32 | E8 xx xx xx xx |
| call dword ptr [EAX] | FF 10 |
| call dword ptr [ECX] | FF 11 |
| call dword ptr [edx] | FF 12 |
| call dword ptr [ebx] | FF 13 |
| call dword ptr [REG * SCALE+BASE] | FF 14 xx |
| call dword ptr [Address] | FF 15 xx xx xx xx |
| call dword ptr [ESI] | FF 16 |
| call dword ptr [EDI] | FF 17 |
| call dword ptr [EAX+xx] | FF 50 xx |
| call dword ptr [ECX+xx] | FF 51 xx |
| call dword ptr [EDX+xx] | FF 52 xx |
| call dword ptr [EBX+xx] | FF 53 xx |
| call dword ptr [REG*SCALE+BASE+offset8] | FF 54 xx xx |
| call dword ptr [EBP+xx] | FF 55 xx |
| call dword ptr [ESI+xx] | FF 56 xx |
| call dword ptr [EDI+xx] | FF 57 xx |
| call dword ptr [EAX+xxxxxxxx] | FF 90 xx xx xx xx |
| call dword ptr [ECX+xxxxxxxx] | FF 91 xx xx xx xx |
| call dword ptr [EDX+xxxxxxxx] | FF 92 xx xx xx xx |
| call dword ptr [EBX+xxxxxxxx] | FF 93 xx xx xx xx |
| call dword ptr [REG*SCALE+BASE+offset32] | FF 94 xx xx xx xx xx |
| call dword ptr [EBP+xxxxxxxx] | FF 95 xx xx xx xx |
| call dword ptr [ESI+xxxxxxxx] | FF 96 xx xx xx xx |
| call dword ptr [EDI+xxxxxxxx] | FF 97 xx xx xx xx |
| call eax | FF D0 |
| call ecx | FF D1 |
| call edx | FF D2 |
| call ebx | FF D3 |
| call esp | FF D4 |
| call ebp | FF D5 |
| call esi | FF D6 |
| call edi | FF D7 |
| call FAR seg16:Address | 9A xx xx xx xx xx xx |
图

参考资料:
https://zhuanlan.zhihu.com/p/68588184 CALL指令有多少种写法
https://blog.csdn.net/qq_39654127/article/details/88698911 王爽《汇编语言》笔记(详细)
王爽汇编第十章,call和ret指令的更多相关文章
- 王爽汇编第五章,[bx]和loop指令
目录 王爽汇编第五章,[bx]和loop指令 [bx]和loop指令 例子: 王爽汇编第五章,[bx]和loop指令 [bx]和loop指令 [bx]之前我们介绍寄存器的时候,已经很详细的说明过了,b ...
- [汇编学习笔记][第十章 CALL和RET指令]
第十章 CALL和RET指令 call和ret指令都是转移指令,它们都修改CS和IP.经常被共同用于实现子程序的设计.这一章,我们讲解call和ret指令的原理 10.1 ret和retf ret指令 ...
- 第十章 Call 和 Ret 指令
引言 想想程序之间的加载返回过程. call 和 ret 指令都是转移指令,它们都修改 IP,或同时修改 CS 和 IP. call 和 ret 经常被共同用来实现自程序的设计. 这一章,我们讲解 c ...
- 王爽 <<汇编 语言>> 13.6 BIOS中断例程应用
;名称:ILOVEU程序 ;使用BIOS提供的中断例程 assume cs:code code segment main: ;显示背景22*80 ;dh中放行号 ;dl中放列号 bibi: push ...
- 王爽汇编习题2.2(1):给定地址段为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为____到____
此题解题背景默认为8080型CPU,地址总线为16根.(8080-16,8086-20,8088-20,80286-24,80386-32) 16根地址总线寻址能力:(2 ** 16) / 1024 ...
- 王爽汇编语言(第三版)环境搭建(附PDF及工具下载)
一.前言 最近在学习汇编语言,使用的是读者评价非常高的王爽老师写的<汇编语言>(第三版),为了适应现在各个版本的windows操作系统,所以采用VMWare虚拟机来搭建纯DOS环境. 二. ...
- Linux下学习王爽老师的汇编语言
坐起来非常容易,找到这条路确实非常曲折,为了后来的同志们不再纠结,特记录如下: 这几天看汇编语言时,很多人都推荐王爽老师的<汇编语言>,老师的书的确写的很好,但是讲的是ms的汇编,但是总不 ...
- 王爽-汇编语言-综合研究四-不使用main函数编程
(一) 研究目的 使用C语言编程,我们一定要使用main函数么? (二) 研究过程 1) 最初的程序 首先,我们编写一个不写main函数的C语言程序. 程序如下: 在编译的过程中,没有发现错误.在链接 ...
- 汇编-10.0-CALL和RET指令
call和ret指令都是转移指令,他们都是修改IP,或同时修改CS和IP.它们常被共同用来实现子程序设计. 1.ret和retf ret指令用栈中的数据,修改IP的内容,从而实现近转移: retf指令 ...
随机推荐
- Django学习day13随堂笔记
每日测验 """ 今日考题 1.什么是django中间件,它的作用是什么,如何自定义中间件,里面有哪些用户可以自定义的方法,这些方法有何特点 2.基于django中间件的 ...
- SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF0\x9F\x90\xA3\xF0\x9F...' for column
在做微信公众号保存用户数据时出现这种错误,一直不知道是哪里的原因,后来发现那个用户昵称带着一只兔子表情,由于数据库编码限制不能保存数据,所有需要先编码, 用PHP的函数就是base64_encode, ...
- Expression Tree 遍历集合
场景 从接口返回的数据是集合,却是 object 类型的.这个时候需要遍历这个集合.现提供两种方法. 方法一: 因为集合是可枚举的,所以可以尝试转为 IEnumerable 类型,然后遍历即可. st ...
- 定要过python二级选择题第一套
1. 2.https://zhuanlan.zhihu.com/p/199883725 树,队列,二叉树,树的基本回忆 二叉树: 分叉为俩个; 一个是右子树一个是左子树 队列:先进先出 柞:后进先出 ...
- HTML 网页开发、CSS 基础语法——六. HTML基本结构
1.基本骨架 HTML文件最基本的四个标签,组成了网页的基本骨架,包括:<html>. <head>.<title>.<body>四组标签. ① < ...
- P6295-有标号 DAG 计数【多项式求逆,多项式ln】
正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...
- 使用VisualStudioCode开发Vue
前言 本文主要介绍在VisualStudioCode下开发Vue. Nodejs.Npm.Vue的项目搭建参考下面文章. 用后台开发的逻辑理念学习VUE 在Windows下学习Nodejs.Npm和V ...
- mysql8.0.20安装教程,mysql下载安装教程8.0.20
mysql8.0.20下载安装教程 mysql8.0.20安装教程 mysql安装包+mysql学习视频+mysql面试指南视频教程 下载地址: 链接:https://pan.baidu.com/s ...
- 12种 vo2dto 方法,就 BeanUtils.copyProperties 压测最拉胯!【快双11了,别用错喽】
作者:小傅哥 博客:https://bugstack.cn 原文:https://mp.weixin.qq.com/s/Xq7oQg7dYESMYxHVnxX8Dw 沉淀.分享.成长,让自己和他人都能 ...
- 1-Java继承中多态情况特性下变量,方法,静态方法的访问
在Java继承下,多态特性下类成员访问情况 /* 在继承中,变量时静态的绑定的,非静态方法是动态的绑定的,静态方法是静态绑定的 */ class Parent{ int number = 11; pu ...