关于ret指令的理解

脑袋笨,看了很久才明白

书中有这样一道练习题,下面程序中,ret指令执行后,(ip)=0,cs:ip指向代码的第一条指令

assume cs:code
stack segment
 db 16 dup(0)

 stack ends

 code segment
	mov ax,4c00h
	int 21H
start:mov ax,stack
	mov ss,ax
	mov sp,16
	mov ax,0
	push ax
	mov bx,0
	ret
code ends

end start
书中说,cpu执行完ret指令时,进行下面2步操作

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

(2)(sp)=(sp)+2

因为看不懂,所以运行debug了下

关于ret指令的理解

然后照搬公式(1)(ip)=((ss)*16+sp),发现(ss)*16+sp=0bdf0+000e=0bdfe,怎么就得到0bdfe不等于0啊,怎么回事?原来0bdfe就是物理地址啊,(0bdfe)就是物理地址0bdfe指向的内容,我们用-d指令可以这样查看0bdf:e

可以看到该地址内容如图

关于ret指令的理解

0bdf:0000段中    0bdf:e对应00,然后0bdf:f对应剩下的00

所以这个时候ip指向的内容就是00

后来才明白,cpu执行ret其实不就是pop ip么?将此时sp指向的东东放到ip中,sp指向的东东也就是(ss)*16+sp这个地址中的数值啊!mov ax,0  push ax的作用就是将此时栈顶元素设置为0,然后执行push ip就是将ax抛出给ip了。









备注:

db 16 dup(1)
看下这个时候内存中是如何放置信息的

关于ret指令的理解

看到的都是16进制,所以01  中0占了4位,1也占了4位,恰好是8位,也就是一个字节

所以每2个紧挨一起的数字就占用了一个内存单元。

所以0bdf:0000指向的就是最开始的01




备注:关于mov sp,16,用图来理解

关于ret指令的理解

一开始的时候sp为0000,执行网mov ss,ax  mov sp,16后,sp变为0010  *16也就相当于16进制1*16,所以变为0010,注意看,可以看到0bdf指向了另起一行的首地址,因为stack 在一开始的时候默认为16个字节,也就是0bdf:0-0bdf:f  所以sp变为0010也就是指向栈底了。

你可能感兴趣的:(关于ret指令的理解)