2012-09-30 23 views
0

我有这个汇编代码,我认为它的作用是使用printf函数打印。我不是很熟悉C,但是我创建了一个主函数,我打印出printf("%d, %d", x, y),其中x和y都是零。装入C,printf函数

我将C代码转换为程序集,但我得到了完全不同的东西。有人能帮我理解下面的汇编代码是什么吗?

  mov %edx,0x8(%esp) 
      mov %eax,0x4(%esp) 
      movl $0x80486a0,(%esp) 
      call 8048360 <[email protected]> 
+1

程序集根据汇编程序和体系结构不同而不同,可能是一个好主意,可以说你正在使用哪一个,以及C编译器...... – Perkins

回答

3

作为你的组件的非常直译,

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 <[email protected]> 

你的程序会跳转到指定的地址(你的反汇编已确定为printf函数),读取来自堆栈内的值,执行打印操作,并然后返回到您的代码,在您拨打电话后的下一条指令恢复操作。

我要去猜测,你的源看起来是这样的:

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

根据您的OS /编译器,你可能会保证EAX和EDX将在启动时的值为0。或者你可能会错过你的代码片段中的初始化代码。

+0

+1这样一个很好的解释。:) –

+0

谢谢你回答:D,但我有一个问题:什么是“代码片段的初始化代码”。 – FranXh

4

从事物的外表,这使三个参数压入堆栈 - 两个整数从edxeax,再加上看起来像一个地址来 - 大概地址它挑来存储字符串文字(即,格式字符串)。之后,它叫printf

所以,底线是它看起来像你在你的问题中提供的源代码的一个非常简单的实现。

1

mov %edx,0x8(%esp):正在将edx的值移到堆栈指针(带有0x8偏移量)。
mov %eax,0x4(%esp):请参阅上文。
movl $0x80486a0,(%esp):正在将地址0x80486a0加载到堆栈指针中。
call 8048360 <[email protected]>:正在调用函数printf。

+0

谢谢你的回答,但我有一个问题。我仍然不明白这条线是如何在我的代码中完成的:movl $ 0x80486a0,(%esp):将地址0x80486a0加载到堆栈指针中。 – FranXh

+0

这不是你的代码,它是调用函数的标准方式。无论何时调用任何函数,这都是在汇编级别执行的方式。堆栈指针填充了函数的起始地址,以便系统知道下一个要执行的代码行。当代码加载地址为0x80486a0的堆栈指针时,这意味着,驻留在内存中的地址0x80486a0处的代码将在接下来执行。 –