GCC内联汇编到二进制

时间:2017-01-31 04:19:12

标签: gcc assembly compilation

在C或C ++中,您可以通过执行以下操作来实现内联汇编指令:

asm("assembly code");  

__asm__ ("assembly code");  

示例:

asm("movl %ebx, %eax"); /* moves the contents of ebx register to eax */
__asm__("movb %ch, (%ebx)"); /* moves the byte from ch to the memory pointed by ebx */

然后,您可以生成交互以在汇编代码和C / C ++变量之间交换值:有关here的更多内容。

我的问题是:编译器是否将每个内联汇编指令直接转换为二进制对应命令?或者这只是一种“仿真”?这就是我想知道你是否实际访问处理器的寄存器,或者代码中处理的所有数据都存储在堆栈中,模拟汇编指令。对不起,如果问题是愚蠢的。

1 个答案:

答案 0 :(得分:0)

当您使用'__ asm __''asm'关键字时,GCC / G ++会将字符串解析为汇编指令。如果您使用'扩展程序集',那么当您在字符串后面包含冒号以使变量与寄存器的'输入/输出'交互时,内联汇编程序执行简单替换,就像在以下示例中一样:

  

__ asm __(“\ _       添加%ebx,%eax; \
      mov%ebx,%ecx; \
      “:”= c“(output_variable):”b“(first_operand),”a“(second_operand):/ *此处不需要* /);

注意每个装配线末尾的反斜杠。它是为了逃避行跳转,以便使用一对引号来使所有汇编代码都能使用。另外,为了帮助内联汇编解析器,每个汇编指令必须以分号结尾

在双引号之间的指令之后,你可以在前两个之间添加三个冒号,声明要接收输出的变量。请注意“= c”(output_variable)表示存储在 ecx 寄存器末尾的值将被转发到()之间的变量

在最后两个冒号之间,您声明将用作输入的变量/值,因此在代码的开头,括号之间的值被分配给用引号之间的字母表示的寄存器(使用comas)对于多个输入)。

在最后一次冒号之后,列出一些破坏的寄存器。然而,在这种特殊情况下,这是可选的并且无用。有关整个GCC内联汇编的更多信息here

因此,总而言之,执行是这样的:

  • 将输入值(如果有)替换为相应的寄存器
  • 从汇编翻译成二进制文件
  • 将输出加载到指定的变量中(如果有)

所以简短的回答是,一旦代码被编译成机器语言,转换将是1对1,就像一个普通的汇编程序,因此它将使用真正的寄存器