1- ret 相当于 pop IP;用栈中数据,修改IP内容.从而实现近转移.
执行后(IP)=0, CS:IP指向代码段的第一条指令.
1 assume cs:code 2 stack segment 3 db 16 dup(0) 4 stack ends 5 code segment 6 mov ax,4c00h 7 int 21h 8 start: 9 mov ax,stack 10 mov ss,ax 11 mov sp,16 12 mov ax,0 13 push ax 14 mov bx,0 15 ret 16 code ends 17 end start
2- retf 相当于 pop IP; pop CS;用栈中数据修改CS,IP内容.从而实现远转移.
执行后 CS:IP指向代码段的第一条指令.
1 assume cs:code 2 stack segment 3 db 16 dup(0) 4 stack ends 5 code segment 6 mov ax,4c00h 7 int 21 8 start: 9 mov ax,stack 10 mov ss,ax 11 mov sp,16 12 mov ax,0 13 push cs 14 push ax 15 retf 16 code ends 17 end start
reference:
http://bbs.csdn.net/topics/340237304
3- 实现从内存1000:0000处开始执行指令
1 assume cs:code 2 stack segment 3 db 16 dup(0) 4 stack ends 5 code segment 6 mov ax,4c00h 7 int 21 8 start: 9 mov ax,stack 10 mov ss,ax 11 mov sp,16 12 mov ax,1000H 13 push ax 14 mov ax,0 15 push ax 16 retf 17 code ends 18 end start
4- call 标号 (将当前的IP压栈后,转到标号处执行指令)
push Ip
jmp near ptr 标号
1 assume cs:code 2 code segment 3 start: 4 mov ax,0 5 call s 6 inc ax 7 s: 8 pop ax 9 code ends 10 end start
ax=6
CPU指令执行的过程:
1- 从CS:IP指向的内存单元读取指令,读取的指令,进入指令缓冲器.
2- (IP) = (IP) + 所读取的指令长度, 从而指向下一条指令
3- 执行指令, 转到1, 重复这个过程
5- call far ptr 标号
push cs
push ip
jmp far ptr 标号
执行步骤分析:
CS:1000 IP:3 时 读取call far ptr s放入缓存, ip = IP + 5 = 8
push cs //1000
push ip //8
跳转到s执行
pop ax //ax = 8
add ax,ax // ax = 8 + 8 = 10 寄存器中存放的数为16进制
pop bx //bx = 1000
add ax,bx //ax = 1000 + 10 = 1010
最终结果 ax = 1010
6- call 16位寄存器
push IP
jmp 16位寄存器 // mov IP,16位寄存器; jmp IP
ax=000B
sp是栈顶地址,[bp]栈顶值为5
ax = 6 + 5 = B
reference:
http://bbs.csdn.net/topics/100016651