0

我有这个汇编代码,我认为它的作用是使用该printf函数进行打印。我对 C 不是很熟悉,但我创建了一个 main 函数并打印出printf("%d, %d", x, y)x 和 y 都为零的位置。

我将 C 代码转换为汇编,但我得到了完全不同的东西。有人可以帮我理解下面的汇编代码的作用吗?

            mov    %edx,0x8(%esp)
            mov    %eax,0x4(%esp)
            movl   $0x80486a0,(%esp)
            call   8048360 <printf@plt>
4

3 回答 3

6

作为您的程序集的非常直译,

mov    %edx,0x8(%esp)

将 edx 中的值移动到堆栈中偏移量 8 (esp + 8)

mov    %eax,0x4(%esp)

将 eax 中的值移动到堆栈的偏移量 4 (esp + 4)

movl   $0x80486a0,(%esp)

将 [32 位值] 0x80486a0 移动到堆栈的偏移量 0

这是将函数的参数放在堆栈上的一种非常基本的方式——RTL 或 C 顺序。最低偏移量的值是第一个参数(在这种情况下,是字符串文字在内存中的地址),最高偏移量的值是最后一个参数。

当您拨打电话时:

call   8048360 <printf@plt>

您的程序将跳转到给定地址(反汇编程序已将其识别为 printf 函数),从堆栈中读取值,执行打印操作,然后返回到您的代码,在您调用后的下一条指令处恢复操作。

我猜你的来源看起来像这样:

void main()
{
    int x =0, y=0;
    printf("%d, %d", x, y);
}

根据您的操作系统/编译器,您可能会保证 eax 和 edx 在启动时的值为 0。或者您可能缺少代码段中的初始化代码。

于 2012-09-30T04:01:12.257 回答
4

从表面上看,这会将三个参数放入堆栈——两个整数来自edxand eax,加上看起来像地址的东西——大概是它选择存储字符串文字的地址(即格式字符串)。之后,它调用printf.

因此,最重要的是,它看起来像是您在问题中提供的源代码的一个非常简单的实现。

于 2012-09-30T03:51:13.770 回答
1

mov %edx,0x8(%esp):正在将 edx 的值移动到堆栈指针(偏移量为 0x8)。
mov %eax,0x4(%esp): 参考上面。
movl $0x80486a0,(%esp):正在加载堆栈指针中的地址 0x80486a0。
call 8048360 <printf@plt>: 正在调用函数 printf。

于 2012-09-30T04:02:35.717 回答