在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的更多内容。
我的问题是:编译器是否将每个内联汇编指令直接转换为二进制对应命令?或者这只是一种“仿真”?这就是我想知道你是否实际访问处理器的寄存器,或者代码中处理的所有数据都存储在堆栈中,模拟汇编指令。对不起,如果问题是愚蠢的。
答案 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,就像一个普通的汇编程序,因此它将使用真正的寄存器