我想知道,根据实际指令读取输入变量是否有限制?
我正在尝试读取内联程序集中的输入变量,以便.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
汇编程序的正确语法。