-2

私はここで何を間違っているのですか?

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

eaxで15を移動してから、割り込みを呼び出したい

"エラー":'asm':オペランド番号が範囲外です

4

2 に答える 2

6

asmコンストラクトは独立しており、一方に設定された値/レジスタは他方とは関係ありません。これを機能させるには、単一のasm. さらに、実際に値を eax に移動する必要はありません。これは、「a」入力制約が行うことです。あなたが望んでいるのは:

int val=15
asm volatile("int $0x80" : : "a"(val));

あるいは単に

asm volatile("int $0x80"::"a"(15));

編集

さまざまな制約文字の意味はgcc のドキュメントにありますが、基本的に 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 レジスターに格納されます。

特定のレジスタに対応しない制約については%n、asm 文字列で使用し、コンパイラによって選択されたレジスタに置き換えられますが、特定のレジスタに対応する制約については、直接言及する必要はありません。 .

于 2013-02-05T02:35:04.710 に答える
0

次のコード例では、x を明示的に EAX に入れているようです。

GCCインラインアセンブリ言語のr()とダブルパーセント%%とは何ですか?

そのコードを 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) info register eax ebx
eax 0xf 15
ebx 0x0 0
(gdb) step
35 asm volatile ("int $0x80");
(gdb) 情報レジスタ eax ebx
eax 0x23 35
ebx 0x23 35

于 2013-02-05T03:31:13.987 に答える