首页 > 编程语言 > 详细

汇编1 ----C语言函数1

时间:2015-04-11 23:42:34      阅读:293      评论:0      收藏:0      [点我收藏+]

构造以下C程序并在合适位置插入breakpoints

技术分享

在Visual Studio 2015 CTP6对其反汇编。

下面来分析

z = add(1, 2);

009C170E 6A 02 push 2

????int z;

????z = add(1, 2);

009C1710 6A 01 push 1

009C1712 E8 8D FA FF FF call 009C11A4

009C1717 83 C4 08 add esp,8

009C171A 89 45 F8 mov dword ptr [ebp-8],eax

第一二行将参数1,2压栈,由此可证明C语言函数参数入栈顺序是从右向左。单步执行push 1 和push 2,观察寄存器的值,可知每将一个参数压入栈,ESP值都要减4。执行push 1后查看ESP所指内存的值。

技术分享

可以看到刚刚压入的2和1,ESP是用来存储栈顶指针的寄存器。

接下来分析下一行 E8 8D FA FF FF

E8为call指令机器码,由小端机存储可知e8的值为ff ff fa 8d。

call目标地址=call指令当前地址+5字节(call指令占用空间)- e8后指令的补码。即009C11A4

call指令执行完毕后,跳转到函数的主体部分。记录返回地址009C1717。那么函数如何返回?单步执行call指令后发现ESP的值由00ACF744变成00ACF664,由于ESP变化较大,笔者猜测函数有可能使用了私有栈。而且00ACF664的内容与返回地址无关。我们直接将call之前ESP的地址减4并查看其内容

技术分享

恰好为函数的返回地址,即call指令执行后,栈顶指针改变,返回地址被压入函数执行前的栈。

Call指令作用相当于 1.压栈返回地址 2.跳转到目标指令。

Intel官方手册上的说明:

Prior to branching to the first instruction of the called procedure, the CALL instruction pushes the address in the EIP

register onto the current stack. This address is then called the return-instruction pointer and it points to the

instruction where execution of the calling procedure should resume following a return from the called procedure.

Upon returning from a called procedure, the RET instruction pops the return-instruction pointer from the stack

back into the EIP register. Execution of the calling procedure then resumes.

以及CALL和RET指令的准备工作

Near call

When executing a near call, the processor does the following (see Figure 6-2):

1. Pushes the current value of the EIP register on the stack.

2. Loads the offset of the called procedure in the EIP register.

3. Begins execution of the called procedure.

When executing a near return, the processor performs these actions:

1. Pops the top-of-stack value (the return instruction pointer) into the EIP register.

2. If the RET instruction has an optional n argument, increments the stack pointer by the number of bytes

specified with the n operand to release parameters from the stack.

3. Resumes execution of the calling procedure.

Far call

1. Pushes the current value of the CS register on the stack.

2. Pushes the current value of the EIP register on the stack.

3. Loads the segment selector of the segment that contains the called procedure in the CS register.

4. Loads the offset of the called procedure in the EIP register.

5. Begins execution of the called procedure.

When executing a far return, the processor does the following:

1. Pops the top-of-stack value (the return instruction pointer) into the EIP register.

2. Pops the top-of-stack value (the segment selector for the code segment being returned to) into the CS register.

3. If the RET instruction has an optional n argument, increments the stack pointer by the number of bytes

specified with the n operand to release parameters from the stack.

4. Resumes execution of the calling procedure.

技术分享

不难看出,far call是带有segment的跳转,用到了CS寄存器。

(未完待续)

汇编1 ----C语言函数1

原文:http://www.cnblogs.com/puorc/p/4418623.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!