9

X86 GNUアセンブリのそのマクロの何が問題になっていますか?リンク中はシンボルSが未定義であると表示されます。

.macro S size=40
\size
.endm

私はそれを次のように使用しています

mov %eax, S
4

2 に答える 2

21

マクロは、定数を入力するのではなく、頻繁に使用するコードのテンプレートを作成するために使用されます。そのため、アセンブラが式内でマクロ展開を行うとは思いません。単に数値が必要なので.set、定数を定義するために使用できます。

.set S, 40
mov %eax, S

また、通常Intel構文を使用する場合は、このコードが何をしているのかを理解してください。現在、eaxの値はメモリのアドレス0x28に格納されています。数値40をeaxに入れたい場合は、オペランドを逆にして、Sの前にドル記号を使用する必要があります。

mov $S, %eax
于 2011-05-05T16:42:09.370 に答える
3

等号の付いた記号を直接割り当てることもできます=

S = 40

マニュアルによるとGNUは、.set https://sourceware.org/binutils/docs-2.19/as/Setting-Symbols.html#Setting-Symbolsを使用するのと同じです。

シンボルを書き込むことにより、シンボルに任意の値を与えることができます。その後に等号=', followed by an expression (see Expressions). This is equivalent to using the .set directive. See .set. In the same way, using a double equals sign='` ='が続きます。ここでは、.eqvディレクティブと同等のものを表します。.eqvを参照してください。

.equさらに別の同義語です...

 .equ S, 40

このような定数の一般的な使用例の1つは、静的文字列の長さを計算することです。たとえば、Linux x86_64helloworldは次のように記述できます。

hello_world.S

    .data
hello_world:
    .ascii "hello world\n"
    hello_world_len = . - hello_world
.text
.global _start
_start:
    /* write */
    mov $1, %rax
    mov $1, %rdi
    mov $hello_world, %rsi
    mov $hello_world_len, %rdx
    syscall

    /* exit */
    mov $60, %rax
    mov $0, %rdi
    syscall

これをコンパイルして実行できます:

as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out

GitHubアップストリーム

%rdx次に、書き込まれる文字列の長さが含まれます。

これ$は、通常のアドレスラベルの場合と同じように必要です。そうでない場合は、即時に移動するのではなく、そのメモリアドレスにアクセスしようとします。

于 2019-01-08T18:04:33.303 に答える