汇编语言(王爽)10章call,ret和offset

ret 用栈中数据改IP内容,近转移
retf用栈中数据同时改CS,IP,远转移
用汇编解释

  • ret -> pop ip
  • retf -> pop ip; pop cs
  • push先修改sp再放数据,pop先取数据再修改sp

call指令
当执行call指令时,进行两步操作:
1)将当前的IP或CS和IP压入栈中
2)转移

call指令不能实现短转移,它的书写格式同jmp指令

  • 依据标号进行转移的call指令
    语法格式:call 标号
    汇编解释:(1) push IP (2) jmp near ptr 标号
  • 依据目的地址在指令中的call指令
    语法格式:call far ptr 标号
    汇编解释:(1) push CS (2) push IP (3) jmp far ptr 标号
  • 转移地址在寄存器中的call指令
    语法格式:call 16位reg
    汇编解释:(1) push IP (2) jmp 16位reg
  • 转移地址在内存中的call指令
    语法格式一:call word ptr 内存单元地址
    汇编解释一:(1) push IP (2) jmp word ptr 内存单元地址
  • 语法格式二:call dword ptr 内存单元地址
    汇编解释二:(1) push CS (2) push IP (3) jmp dword ptr 内存单元地址

检测点10.2
下面的程序执行后,AX中的数值为多少?

assume cs:codesg 
codesg segment  
 start:  
        mov ax,0 	//b8 00 00
        call s 		//e8 01 00
        inc ax 		//40
       s:pop ax  	//58
codesg ends   
end start  

走到call s 时,IP值已经完成自动增加,此时IP=6
执行call s之后,IP=6 被压入栈
执行pop ax,使得的 (ax)=6

检测点10.3
下面的程序执行后,AX中的数值为多少?

内存地址       机器码          		汇编指令  

10000       b8 00 00     			mov ax,0  
10003       9A 09 00 00 10        call far ptr s   
10008       40                	inc ax   
10009       58           			s:  pop ax 			 ;ax=8h  
                             		add ax,ax 			;ax=10h  
                              		pop bx 				;bx=1000h  
                             		add ax,bx			 ;ax=1010h  

执行call far ptr s时,取IP为8,add ax,ax ax=16
BX=CS=1000H 相加转16进制ax=1010H

检测点10.4
下面的程序执行后,AX中的数值为多少?

内存地址        机器码          汇编指令   
10000       b8 06 00      	mov ax,6   
10002       ff d0             call ax
10005       40                inc ax   
10006                   		s: mov bp,sp   
	                              add ax,[bp]

call ax后栈顶的数据时0005,ip=0006,[bp]就是栈顶=0005,所以ax=0006+0005=000bh

检测10.5
01,下面程序执行后 , ax 中的值是什么 ?

assume cs:code,ss:stack
stack segment
    dw 8 dup(0)
stack ends
code segment
    start:
        mov ax, stack
        mov ss, ax
        mov sp, 0010H
        mov ds, ax
        call word ptr ds:[0EH]
        inc ax
        inc ax
        inc ax
code ends
end start
该题中的程序的数据段和栈段使用了同一段内存 , 也就是说 ds 和 ss 是相同的
执行到 call word ptr ds:[0EH] 的时候 , 具体的流程如下 : 
1. CPU取指令 : (call word ptr ds:[0EH])
2. ip自增上述指令的长度 , 指向了下一条指令 (inc ax)
3. 开始执行该指令
  3.1. push ip ; 将 ip=15 压入栈
  3.2. jmp ds:[0EH]((ip) = ds:[0EH],也就是说程序又从ds:[0EH]中取出数据赋值给 ip
4. 现在其实就开始执行 ip 之前保存的地址的指令了 , 也就是三个 inc ax
5. 因此最终 ax 值为 3  

02 下面的程序执行后 , ax 和 bx 的值是什么 ?

assume cs:code,ds:data
data segment
    dw 8 dup(0)
data ends
code segment
    start:
        mov ax, data
        mov ss, ax
        mov sp, 16
        mov word ptr ss:[0], offset s
        mov ss:[2], cs
        call dword ptr ss:[0]
        nop
    s:
        mov ax, offset s
        sub ax, ss:[0CH]
        mov bx, cs
        sub bx, ss:[0EH]
code ends
end start
mov word ptr ss:[0], offset s把ss的偏移地址保存到ss[0]和ss[1],
mov ss:[2], cs把cs保存到ss[2]和ss[3],
call dword ptr ss:[0]把cs和nop的偏移地址先后压栈,并跳转(ss[0])即s,
所以ax=s的偏移地址-nop的偏移地址=1,bx=cs-cs=0

ret n相当于pop ip;add sp,n
可以在调方法时把参数放进栈,执行完后设置适当的n,使得ret n之后正好把所有参数出栈。

assume cs:code
code segment
	start:  				;//sp=0000
		call f1				;//sp=FFFE
		nop					;//sp=0004
		mov sp,0			;//sp=0000
		call f2				;//sp=FFFE
		
		mov ax,4c00h		;//sp=FFFC
		int 21h
	f1:
		ret 4
	f2:
		ret -4
code ends
end start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值