该汇编代码的作用是什么?C 代码是什么样的?
What does this assembly code do and what would the C code look like?
我正在尝试反汇编文件,其中一个部分包含此文件。这是在做什么?用 C 语言会是什么样子?
我相信它将 40 复制到 ebp-8 并将 20 复制到 ebp-4。然后它调用 func: 函数。它通过将 edx 添加到 eax 然后从中减去 4 来执行一些命令。退出 func: 函数后,它会向 esp 加 8。我在正确的轨道上吗?
func:
push ebp
mov ebp, esp
mov edx, DWORD PTR [ebp+8]
mov eax, DWORD PTR [ebp+12]
add eax, edx
sub eax, 4
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
push DWORD PTR [ebp-4]
push DWORD PTR [ebp-8]
call func
add esp, 8
leave
ret
编辑:那么您是否同意 C 的结果如下?
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int func(int d, int e)
{
int sum = d + e;
int result = sum - 4;
return result;
}
int main(void)
{
int a = 40;
int b = 20;
int c = func(a,b);
printf("Result is: %d\n", c);
}
分解后,代码如下所示:
func:
; enter 0, 0
push ebp
mov ebp, esp
; entered func with no local variables
; get first param in edx
mov edx, DWORD PTR [ebp+8]
; get second param in eax
mov eax, DWORD PTR [ebp+12]
add eax, edx ; eax += edx
sub eax, 4 ; eax -= 4
; to avoid segfault, you should first `mov esp, ebp`
; but works here, since ESP was not changed, so getting back ESP's old value is not required
pop ebp
ret
main:
; enter 16, 0
push ebp
mov ebp, esp
sub esp, 16 ; adds 4 elements on the stack
; entered main with 4 local variables on stack
; writing on 2 local variables
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
; push 2 params on the stack and call `func`
push DWORD PTR [ebp-4] ; second param
push DWORD PTR [ebp-8] ; first param
call func ; calls `func(first, second)`, returns EAX = 56
; delete 2 elements off the stack
add esp, 8
; leave entered function (get back ESP from before entering)
leave
; return to caller
ret
我觉得看了评论里的解释(;
标记),你自己翻译成C代码应该很容易。
编辑:
正如 Peter Cordes 所指出的,Assembly 不知道任何数据类型,例如 int
或 long int
。我在 x86 汇编中,你使用通用寄存器和 C 约定,任何 32 位值在 EAX
中返回,而 64 位值在 EDX:EAX
中返回,这意味着 EDX
的内容将是高 32 位。
但是如果 main
标签是 C 中的经典 int main()
函数和程序的入口点,我们可以假设 func
看起来像 int func(int p1, int p2)
我相信在 C 中也是如此,因为返回的 EDX
从未使用过,并且 int main()
函数似乎以 return 56;
结尾,在 EAX
.
中有 56
我正在尝试反汇编文件,其中一个部分包含此文件。这是在做什么?用 C 语言会是什么样子?
我相信它将 40 复制到 ebp-8 并将 20 复制到 ebp-4。然后它调用 func: 函数。它通过将 edx 添加到 eax 然后从中减去 4 来执行一些命令。退出 func: 函数后,它会向 esp 加 8。我在正确的轨道上吗?
func:
push ebp
mov ebp, esp
mov edx, DWORD PTR [ebp+8]
mov eax, DWORD PTR [ebp+12]
add eax, edx
sub eax, 4
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
push DWORD PTR [ebp-4]
push DWORD PTR [ebp-8]
call func
add esp, 8
leave
ret
编辑:那么您是否同意 C 的结果如下?
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int func(int d, int e)
{
int sum = d + e;
int result = sum - 4;
return result;
}
int main(void)
{
int a = 40;
int b = 20;
int c = func(a,b);
printf("Result is: %d\n", c);
}
分解后,代码如下所示:
func:
; enter 0, 0
push ebp
mov ebp, esp
; entered func with no local variables
; get first param in edx
mov edx, DWORD PTR [ebp+8]
; get second param in eax
mov eax, DWORD PTR [ebp+12]
add eax, edx ; eax += edx
sub eax, 4 ; eax -= 4
; to avoid segfault, you should first `mov esp, ebp`
; but works here, since ESP was not changed, so getting back ESP's old value is not required
pop ebp
ret
main:
; enter 16, 0
push ebp
mov ebp, esp
sub esp, 16 ; adds 4 elements on the stack
; entered main with 4 local variables on stack
; writing on 2 local variables
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
; push 2 params on the stack and call `func`
push DWORD PTR [ebp-4] ; second param
push DWORD PTR [ebp-8] ; first param
call func ; calls `func(first, second)`, returns EAX = 56
; delete 2 elements off the stack
add esp, 8
; leave entered function (get back ESP from before entering)
leave
; return to caller
ret
我觉得看了评论里的解释(;
标记),你自己翻译成C代码应该很容易。
编辑:
正如 Peter Cordes 所指出的,Assembly 不知道任何数据类型,例如 int
或 long int
。我在 x86 汇编中,你使用通用寄存器和 C 约定,任何 32 位值在 EAX
中返回,而 64 位值在 EDX:EAX
中返回,这意味着 EDX
的内容将是高 32 位。
但是如果 main
标签是 C 中的经典 int main()
函数和程序的入口点,我们可以假设 func
看起来像 int func(int p1, int p2)
我相信在 C 中也是如此,因为返回的 EDX
从未使用过,并且 int main()
函数似乎以 return 56;
结尾,在 EAX
.