王爽老师汇编语言第四版第十章CALL和RET指令——小白笔记

目录

10.1 ret和retf

(1)  ret:

(2)retf:

10.2 call指令

10.3依据位移进行转移的CALL指令

10.4 转移的目的地址在指令中的CALL指令

10.5转移地址在寄存器中的CALL指令

10.6转移地址在内存中的call指令

10.7call和ret指令的配合使用

10.8 mul指令

10.9模块化程序设计

10.10参数和结果的传递问题

10.11批量数据的传递

10.12寄存器冲突问题


        从这一章开始,开始以小节为单位视频课本结合看,之前都是看完一章视频后再看课本,当然有不足,那就是不知道视频讲的啥,从这一章开始,以每一小节为单位,并且,小节也是结合看,并没有先后之分,希望这样的学习效率更高些。

        

        第十章讲的是call和ret 指令,他们修改IP或同时修改IP和CS。经常共同实现子程序设计。

10.1 ret和retf

(1)  ret:

        ip=((ss)*16+(sp))

        (sp)=(sp)+2

        从而实现ip的修改实现近转移

        其实就相当于:

        pop ip

(2)retf:

        ip=((ss)*16+(sp))

        (sp)=(sp)+2

        cs=((ss)*16+(sp))

          (sp)=(sp)+2

        

        从而实现ip的修改和cs的修改实现远转移     

        

  其实就相当于:

        pop ip

        pop cs

10.2 call指令

cpu执行call指令进行两步操作

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

(2)转移

CALL不能实现短转移,另外call转移和jmp指令的原理相同。

10.3依据位移进行转移的CALL指令

CALL标号:

将当前的IP压入栈后再转移到标号处执行指令

(注意当前IP是执行CALL的下一条指令,CALL的下一条指令只是被IP所指过,但是并没有被执行,因为IP立即就改变了)

CPU执行此种格式的CALL指令时,进行如下操作

(1)(sp)=(sp)-2

((ss)*16+(sp))=(IP)

(2)(IP)=(IP)+16位位移

(1)16位位移=标号的偏移地址-call指令的下一条指令的第一个字节的地址

(2)16位位移范围是-32768~32767用补码表示

(3)16位位移由编译程序在编译时算出

CLL  标号

push IP

jmp near ptr 标号

*在dosbox中可以用r cs或者 r IP 修改cs  ip 以达到目的去执行相应的指令

*或者用a 指令修改此时所指向的cs:ip的命令

-a jmp 要跳转到的段地址:偏移地址

10.4 转移的目的地址在指令中的CALL指令

前边的CALL指令,其对应的机器码指令中并没有转移的目的地址,而是相对于当前IP的转移位移。

CALL far ptr 标号    实现的是段间偏移

CUP执行时进行的操作

(1)将SP 和SS分别入栈

(sp)=(sp)-2

((ss)*16+(sp))=(CS)          *将cs入栈

(sp)=(sp)-2

((ss)*16+(sp))=(IP)

(2)完成跳转

(CS)=标号所在段地址

(IP)=标号所在偏移地址  

call far ptr 标号相当于:

push CS

push IP

push far ptr 标号

10.5转移地址在寄存器中的CALL指令

call 16位寄存器

操作

(sp)=(sp)-2   

((ss)*16+(sp))=(IP)

上两步操作为入栈操作,将call 寄存器指令的下一条指令的ip入栈

(IP)=(16位reg) *跳转

监测点10.4

用[bp]寻址时默认段地址在ss

10.6转移地址在内存中的call指令

两种格式:

(1)call word ptr 内存单元地址

push ip

jmp word ptr 内存单元地址

(2)call dword ptr 内存单元地址

push cs  *先cs

push ip  * 后ip

jmp dword ptr 内存单元地址

会先修改ip(内存单元16位地址) 在修改cs(内存单元高16位)

10.7call和ret指令的配合使用

我们知道call指令是将IP入栈,而ret指令是将IP出栈,那么我们就可以将两者结合起来实现子程序的调用,我所理解的就是C语言中的函数调用,大致框架是这样的,

标号:

        指令

        ret

具有子程序的云程序框架如下

assume cs:code
code segment

main: ;.............  


    call  sub1      ;调用子程序sub1
    mov ax,4C00h
    int 21h





    sub1:;........  ;子程序sub1开始
        call sub 2  ;子程序sub2开始



        ret         ;子程序返回

    sub2:;...
        ret         ;子程序返回

code ends
end main

10.8 mul指令

mul乘法指令

(1)两个相乘的数:要么都是8位要么都是16位。如果都是8位,一个默认放在AL中,另一个放在8位reg中或者内存字节单元中。如果是16位,一个默认放在AX中,另一个放在16位reg或内存单元字单元中。

(2)结果:8位乘法的结果默认放在AX中,16乘法高位在DX中,低位在AX中。

格式:

mul   ret

mul 内存单元

mul byte ptr ds:[0]

mul word ptr [bx+si+8] 

10.9模块化程序设计

将复杂的问题转化成简单的问题,使用call和ret指令

10.10参数和结果的传递问题

10.11批量数据的传递

寄存器的数量是有限的,如果数据过多可以将数据放到内存单元中,来进行读取和写入。

10.12寄存器冲突问题

为了避买子程序使用寄存器和主程序使用的寄存器发生冲突,我们通常在子程序的开始将所用到的寄存器push到栈中保护起来,在ret前再将所push的寄存器pop出来(顺序相反)

由于时间问题,索性将课程设计放到最后,所以先不整理课程设计的内容。直接进行下一章的笔记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y6y6y666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值