X86 GNUアセンブリのそのマクロの何が問題になっていますか?リンク中はシンボルSが未定義であると表示されます。
.macro S size=40
\size
.endm
私はそれを次のように使用しています
mov %eax, S
X86 GNUアセンブリのそのマクロの何が問題になっていますか?リンク中はシンボルSが未定義であると表示されます。
.macro S size=40
\size
.endm
私はそれを次のように使用しています
mov %eax, S
マクロは、定数を入力するのではなく、頻繁に使用するコードのテンプレートを作成するために使用されます。そのため、アセンブラが式内でマクロ展開を行うとは思いません。単に数値が必要なので.set
、定数を定義するために使用できます。
.set S, 40
mov %eax, S
また、通常Intel構文を使用する場合は、このコードが何をしているのかを理解してください。現在、eaxの値はメモリのアドレス0x28に格納されています。数値40をeaxに入れたい場合は、オペランドを逆にして、Sの前にドル記号を使用する必要があります。
mov $S, %eax
等号の付いた記号を直接割り当てることもできます=
。
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
%rdx
次に、書き込まれる文字列の長さが含まれます。
これ$
は、通常のアドレスラベルの場合と同じように必要です。そうでない場合は、即時に移動するのではなく、そのメモリアドレスにアクセスしようとします。