deg*_*ion 2 c c++ x86 assembly
我一直在编写一个C应用程序,我需要x86汇编语言.我对汇编很新,下面的代码片段会导致递归:
unsigned int originalBP;
unsigned fAddress;
void f(unsigned short aa) {
printf("Function %d\n", aa);
}
unsigned short xx = 77;
void redirect() {
asm {
pop originalBP
mov fAddress, offset f
push word ptr xx
push fAddress
push originalBP
}
}
Run Code Online (Sandbox Code Playgroud)
如果我打电话redirect,它会反复输出:"功能1135"
首先,以下是有关执行此代码的环境的一些信息:
这是我对上面代码应该做什么的期望(这很可能是错误的罪魁祸首):
originalBP; 我相信这个值实际上是当前函数的地址,即redirectf参数值(值xx)推送到堆栈f堆栈的地址(因为只有一个段,只需要偏移)redirect当然,如果这是正确的流程,递归将是明显的(除了打印1135而不是7的部分).但有趣的是,对于没有参数的函数执行相同操作只会产生一行输出,即:
unsigned int originalBP;
unsigned fAddress;
void f() {
printf("Function");
}
void redirect() {
asm {
pop originalBP
mov fAddress, offset f
push fAddress
push originalBP
}
}
Run Code Online (Sandbox Code Playgroud)
这可能意味着我对上述代码的理解是完全错误的.这段代码中的真正问题是什么?
编辑:我可能留下了一些未说明的事情:
redirect从所谓main的redirect()编辑(关于玛格丽特布鲁姆的回答)这是一个redirect被调用的指令执行的例子.括号中的值表示堆栈指针寄存器以及每个指令执行前该位置的值:
push bp mov bp, sp mov fAddress, offest f pop originalBP pop originalRIP push xx(我已将xx更改为1187)push originalRIPpush fAddresspush originalBPpop bp ret
push bpmov bp,sppop bp ret
接下来的陈述似乎return 0;是主要的结尾. 执行继续通过一堆线,并以某种方式回到线路调用redirect.
对于你的第二个片段,没有参数的片段,堆栈状态如下:
Where | Stack (growing on the left)
----------------------+----------------------------
after redirect prolog redirect rip, redirect bp
pop originalBP redirect rip
push fAddress redirect rip, fAddress
push originalBP redirect rip, fAddress, redirect bp
after redirect epilog redirect rip, fAddress
after redirect return redirect rip (control moved to f)
after f prolog redirect rip, f bp
after f epilog redirect rip
after f return (control moved to redirect caller)
Run Code Online (Sandbox Code Playgroud)
其中redirect rip表示函数的返回地址(返回IP)redirect.
正如您所看到的,在f正确输入堆栈时redirect rip,返回地址为redirect.退出时,控件返回给redirect调用者.
对于您的第一个代码段,堆栈如下:
Where | Stack (growing on the left)
----------------------+----------------------------
after redirect prolog redirect rip, redirect bp
pop originalBP redirect rip
push word ptr xx redirect rip, xx
push fAddress redirect rip, xx, fAddress
push originalBP redirect rip, xx, fAddress, redirect bp
after redirect epilog redirect rip, xx, fAddress
after redirect return redirect rip, xx (control moved to f)
after f prolog redirect rip, xx, f bp
after f epilog redirect rip, xx
after f return (control moved to xx)
Run Code Online (Sandbox Code Playgroud)
当f我们进入redirect rip, xx时,我们应该在堆栈上xx, redirect rip.
使用前一个配置,参数aa包含返回地址redirect和返回地址f的值是xx.
如果要f使用参数调用,请确保在返回地址之前将它们推送:
pop originalBP
pop originalRIP
;Arguments go here
push xx
push originalRIP
push fAddress
push originalBP
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |