c语言 - 具有内联程序集的读取变量



我想知道,根据实际指令读取输入变量是否有限制?

我正在尝试读取内联程序集中的输入变量,以便.rept指令重复指令x次数。

但是,汇编人员抱怨:Error: negative count for REPT - ignored

这是我的方法:

const int x = 42;
__asm__ volatile (".rept %[in]" :: [in] "m" (x));
__asm__ volatile (".endr");

尝试将变量值加载到寄存器中的工作方式与预期一样:

int function(void) {
const int x = 42;
__asm__ volatile ("mov %[in], %%eax" :: [in] "m" (x));
__asm__ volatile ("ret");
}

返回42,反汇编看起来符合预期。

我尝试在汇编中编写它以查看常量是否可以与.rept指令一起使用,它确实这样做

global _start
section .data
nvalue  equ     39
section .text
_start:
push    rbp
mov     rbp,    rsp
%rep nvalue
nop
%endrep
mov     rax,    60
mov     rdi,    nvalue
syscall

反汇编看起来符合预期:

Disassembly of section .text:
0000000000401000 <_start>:
401000:       55                      push   rbp
401001:       48 89 e5                mov    rbp,rsp
401004:       90                      nop
...
40102d:       90                      nop
40102e:       b8 3c 00 00 00          mov    eax,0x3c
401033:       bf 2a 00 00 00          mov    edi,0x2a
401038:       0f 05                   syscall

我是否将.rept%rep混淆了,它们不代表相同的操作吗?

任何帮助将不胜感激。

如注释中所述,i操作数通常会插入前导$符号,这在 AT&T 语法中作为直接操作数是正确的,但不适用于像.rept这样的汇编指令。 您可以使用c修饰符禁止此操作,请参阅 GCC 手册的第 6.47.2.8 节:

void many_nops(void) {
const int num = 42;
asm(".rept %c0 ; nop ; .endr" : : "i" (num));
}

这将内联 42nop指令。 当然,这只有在num可以折叠为编译时常量时才有效;特别是,您必须使用优化进行编译才能正常工作。

试穿神螺栓

您也可以将英特尔 asm 语法与-masm=intel一起使用,其中常量首先不会获得前导$

请注意,您的内联 asm 还有许多其他问题(您无法从内联 asmret,不应在多个asm语句之间拆分代码等),因此您可能想从阅读 https://stackoverflow.com/tags/inline-assembly/info 中的一些常见问题解答开始。

.rept%rep的问题:第一个是通常用于组装GCC输出的GNU汇编程序gas的正确语法,第二个是nasm汇编程序的正确语法。

最新更新