我在这里做错了什么?
int val = 15;
asm ("movl %1, %%eax"::"r"(val):"%eax" );
__asm__ volatile ("int $0x80");
我想在 eax 中移动 15,然后调用中断
"Error" : 'asm': operand number out of range
最佳答案
每个 asm
构造都是独立的,其中设置的值/寄存器与另一个构造没有任何联系。为了完成这项工作,您需要一个 asm
。此外,不需要实际将值移动到 eax 中——这就是“a”输入约束的作用。所以你想要:
int val=15
asm volatile("int $0x80" : : "a"(val));
或者只是
asm volatile("int $0x80"::"a"(15));
编辑
各个约束字母的含义在 the gcc documentation ,但基本上,对于 x86 它们是:
'r' -- any general register
'm' -- in memory addressable by an EA operand (base reg + index * scale + displacement)
'a' -- al/ax/eax/rax register (depending on the size of the operand)
'b' -- bl/bx/ebx/rbx register
'c' -- cl/cx/ecx/rcx register
'd' -- dl/dx/edx/rdx register
'A' -- edx:eax register pair (holding a 64-bit value)
'D' -- di/edi/rdi
'S' -- si/esi/rdi
'f' -- any 8087 fp register
't' -- ST(0) -- top of 8087 stack
'u' -- ST(1) -- second on 8087 stack
'y' -- any MMX register
'x' -- any XMM register
如果您想将多个内容放入特定寄存器中,则需要多个输入,每个输入都有适当的约束。例如:
int read(int fd, void *buf, int size) {
int rv;
asm ("int $0x80" : "=a"(rv) : "a"(3), "b"(fd), "c"(buf), "d"(size) : "memory");
return rv;
}
直接进行“读取”系统调用。输入约束将各种参数放入eax/ebx/ecx/edx寄存器中,返回值最终放入eax寄存器中。
对于不对应于特定寄存器的约束,您可以在 asm 字符串中使用 %n
,它会被编译器选择的寄存器替换,但对于对应的约束具体寄存器,无需直接提及。
关于存储在 eax 寄存器中的 c 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14699186/