我在这里做错了什么?
int val = 15;
asm ("movl %1, %%eax"::"r"(val):"%eax" );
__asm__ volatile ("int $0x80");
我想在eax中移动15然后调用中断
“错误”:'asm':操作数超出范围
答案 0 :(得分:6)
每个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
,它将被编译器选择的寄存器替换,但对于与特定寄存器对应的约束,没有必要直接提及它。
答案 1 :(得分:0)
看起来他在以下代码示例中明确地将x放入EAX:
What is r() and double percent %% in GCC inline assembly language?
我使用g ++编译了该代码并通过gdb运行它 在gdb中, info register eax 显示正确的数字
您使用的编译器和操作系统和架构是什么?如果您使用的是64位MSVS,则无法进行内联汇编。
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
cout << "Compile via: g++ -O0 -ggdb -o asm.out asm.cpp" << endl;
cout << "Want to put 15 into register EAX and then call an interrupt." << endl;
cout << "gdb ./asm.out --> stepi --> info register eaain." << endl;
int eaxin = 15, eaxout=0, ebxin=33, ebxout=0;
cout << "Before calling assembly routines:" << endl;
cout << "eaxin=" << eaxin << "\t" << "eaxout=" << eaxout << "\t" ;
cout << "ebxin=" << ebxin << "\t" << "ebxout=" << ebxout << endl;
asm ("movl %1, %%eax;"
"movl %%eax, %0;"
:"=r"(eaxout) /* 1 eaxout is output operand 1 */
:"r"(eaxin) /* 0 eaxin is input operand 0*/
:"%eax"
); /* %eax is clobbered register. Why not two percent signs here? */
//Lets play in the ebx register.
asm ("movl %1, %%ebx;"
"inc %%ebx;"
"inc %%ebx;"
"movl %%ebx, %0;"
:"=r"(ebxout)
:"r"(ebxin) /* "+" is supposed to allow input and output but did not work */
:"%ebx"
);
//Call the system interrupt 128.
asm volatile ("int $0x80");
cout << "After calling assembly routines. Value of eaxout should have changed." << endl;
cout << "eaxin=" << eaxin << " " << "eaxout=" << eaxout << "\t" ;
cout << "ebxin=" << ebxin << "\t" << "ebxout=" << ebxout << endl;
cout << endl;
cout << "https://stackoverflow.com/questions/3589157/need-some-help-understanding-gcc-inline-assembly-language?rq=1" << endl;
cout << "Note: inline assembly CANNOT be done with MS VisualStudio 64bit." << endl;
cout << " option1: Use a separate file for the assembler code." << endl;
cout << " option2: Use instrinsics." << endl;
cout << " Look for intrn.h at http://software.intel.com/en-us /node/181178?wapkw=ain86_64+assembly " << endl;
return 0;
}
(gdb)信息注册表eax ebx
eax 0xf 15
ebx 0x0 0
(gdb)步骤
35 asm volatile(“int $ 0x80”);
(gdb)信息注册表eax ebx
eax 0x23 35
ebx 0x23 35