【问题标题】:c variable to store in eax register存储在 eax 寄存器中的 c 变量
【发布时间】:2013-02-05 02:26:52
【问题描述】:

我在这里做错了什么?

int val = 15;
asm ("movl %1, %%eax"::"r"(val):"%eax" );
__asm__ volatile ("int $0x80");

我想在eax中移动15,然后调用中断

“错误”:'asm':操作数超出范围

【问题讨论】:

  • 你认为什么不起作用?
  • 不要通过删除所有相关文本并要求将其删除来编辑您的问题。你不能删除它是有原因的。

标签: c gcc assembly inline-assembly


【解决方案1】:

每个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,它会被编译器选择的寄存器替换,但对于与特定寄存器对应的约束,则有无需直接提及。

【讨论】:

  • Chris 的回答在 asm 块开始之前将 val 放入 eax 中。这就是"a"(val) 的用途。
  • 他把它放在eax的什么地方?我想专门添加它手动注册eax
  • @zoy.khan: "a"(val) is 专门说“将val 放入eax。这个答案为您提供了正确的方法。原因为什么这是正确的方法,是因为它允许编译器知道eax和内联汇编之间的关系。所以优化不会把它搞砸。如果他写了"b"(val),那么它将使用ebx . 这就是它的完成方式。
  • Evan 如果系统调用需要 3 个寄存器,然后执行中断,该怎么办。你会怎么做?
  • @zoy.khan:然后你为两者创建输入。 "a"(val), "b"(other_val)
【解决方案2】:

看起来他在下面的代码示例中明确地将 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

【讨论】:

  • 我想学习如何从c变量中将变量存储在ebx或eax上,请帮助
  • 点击我回答中的链接。它明确引用 eax。您可能希望从关闭所有编译器优化开始,以降低 eax 在中断得到服务之前被其他数据破坏的可能性。
猜你喜欢
  • 2013-04-01
  • 1970-01-01
  • 2013-05-14
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-26
相关资源
最近更新 更多