博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
汇编语言(王爽)-第十章
阅读量:6079 次
发布时间:2019-06-20

本文共 2037 字,大约阅读时间需要 6 分钟。

第十章 CALL和RET指令

一、ret和retf
*ret:功能为:pop ip,实现的是段内近转移;相当于jmp near ptr X
*retf功能为:pop ip,pop cs,实现的是远转移;相当于jmp far ptr X

二、 call指令
*call指令分为两步:

(1)将当前IP压入栈;

(2)设置新IP进行转移。

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

call 标号,功能为:
push IP
jmp near ptr 标号
可看出call的转移操作与jmp near ptr一样,均使用位移进行,位移量为16位。
2、直接使用转移目的地址的call指令
(1)转移目的地址在指令中的call指令:call far ptr 标号
其功能为:
push CS
push IP
jmp far ptr 标号
(2)转移目的地址在寄存器中的call指令:call reg(16位)
其功能为:
push IP
jmp reg(16位)
(3)转移目的地址在内存中的call指令
a.  call word ptr 内存单元地址
其功能为:
push IP
jmp word ptr 内存单元地址
b.  call dword ptr 内存单元地址
其功能为:
push CS
push IP
jmp dword ptr 内存单元地址

检测点10.5

(1)下面程序执行后,ax中数值为多少?

assume cs:codestack segment   dw 8 dup (0)stack endscode segmentstart:  mov ax,stack           ;A  mov ss,ax  mov sp,16  mov ds,ax  mov ax,0             ;B  call word ptr ds:[0eh]     ;C  inc ax    ;D  inc ax  inc ax  mov ax,4c00h  int 21hcode endsend start ;第一次从A开始执行,此时栈段内数值均为0,;运行到C时,先将D处的IP压入stack段,再取出ds:[0eh]处的字数值作为IP;而此时该处数值就为之前压入的D处的IP;所以继续执行D,直到结束。(AX)=3

(2)下面程序执行后,ax和bx中数值为多少?

assume cs:codedata segment   dw 8 dup (0)data endscode segmentstart:  mov ax,data           ;A  mov ss,ax  mov sp,16  mov word ptr ss:[0],offset s   ;B  mov ss:[2],cs                      ;C  call dword ptr ss:[0]             ;D  nop                               ;Nops:  mov ax,offset s             ;E  sub ax,ss:[0ch]             ;F  mov bx,cs                     ;G  sub bx,ss:[0eh]             ;H  mov ax,4c00h  int 21hcode endsend start ;B句把标号s的偏移地址复制到ss:[0]处;C句把cs复制到ss:[2];到D句时候,先将Nop句的CS和IP分别压入栈,对应(ss:0eh)=(CS),(ss:0ch)=(IP);再跳转到对应位置,即s处继续执行;E句给ax赋值标号s的偏移地址;F句用ax的值减去ss:[0ch];即用E处的偏移地址减去Nop的偏移地址;即为NOP的代码长度,即(ax)=1.;同理分析G,H,(bx)=0

 

三、mul指令
1、对于8位×8位运算
其中一个乘数默认在al中,另外一个乘数在8位reg或内存单元中,结果为16位,存在ax中;
2、对于16位×16位运算
其中一个乘数默认在ax中,另外一个乘数在16位reg或内存单元中,结果为32位,高位存在dx,低位存在ax中;
四、模块化程序设计
1、call和ret使得汇编编程中模块化设计的实现;主程序中使用call,暂存主程序中下一指令的地址(IP入栈),同时
调用子程序;子程序中使用ret/retf指令取出前面缓存的主程序指令ip(出栈),返回主程序;
2、参数的使用:对于子程序而言,无法得知可能会调用其的主程序的寄存器使用情况,所以一般情况下,子程序先需要将
用到的寄存器入栈保护,在ret/retf返回前在出栈调出原寄存器值。

转载于:https://www.cnblogs.com/tsembrace/p/3267151.html

你可能感兴趣的文章
【Unity/Kinect】显示Kinect摄像头内容,屏幕显示环境背景及人体投影
查看>>
PHP模拟登录并获取数据
查看>>
css的padding
查看>>
如何判断一条sql(update,delete)语句是否执行成功
查看>>
CSS的!important修改权重
查看>>
spring mvc WebArgumentResolver不生效
查看>>
利用傅里叶变换去除图像中有规律的噪声
查看>>
mysql 悲观锁 的运用
查看>>
Servlet学习:实现分页效果的方法
查看>>
linux设备驱动归纳总结(四):4.单处理器下的竞态和并发【转】
查看>>
总结2016
查看>>
Cobertura 代码覆盖率测试
查看>>
Dev控件删除按钮的两种方式
查看>>
JMeter3.0 post参数/BeanShell中文乱码问题
查看>>
ps常用快捷键
查看>>
SV通过DPI调用C
查看>>
py-faster-rcnn在windows下安装
查看>>
Nodejs 如何开发 module、npm package——directory + index.js + package.json!
查看>>
在win7系统下使用TortoiseGit(乌龟git)简单操作Git@OSC
查看>>
atime、mtime、ctime
查看>>