.code16, .code32, .code64でそれぞれ 16bit, 32bit, 64bit モードでアセンブルしてくれるようです。
まず、レジスタの名前ですが、ビット長ごとに以下の通り。
16bit 32bit 64bit
%ax %eax %rax
%bx %ebx %rbx
%cx %ecx %rcx
%dx %edx %rdx
%si %esi %rsi
%di %edi %rdi
例えば、以下のような test.s というファイルを作る。
.file "test.s"
.text
.code16
main16:
mov (%si), %ax
mov (%si), %eax
mov (%esi), %ax
mov (%esi), %eax
.code32
main32:
mov (%si), %ax
mov (%si), %eax
mov (%esi), %ax
mov (%esi), %eax
.code64
main64:
// mov (%si), %ax
// mov (%si), %eax
// mov (%si), %rax
mov (%esi), %ax
mov (%esi), %eax
mov (%esi), %rax
mov (%rsi), %ax
mov (%rsi), %eax
mov (%rsi), %rax
リストファイルを出してみる。
$ gcc -Wa,-a=test.lst -c -o test.o test.s
$ cat test.lst
GAS LISTING test.s page 1
1 .file "test.s"
2 .text
3
4 .code16
5 main16:
6 0000 8B04 mov (%si), %ax
7 0002 668B04 mov (%si), %eax
8 0005 678B06 mov (%esi), %ax
9 0008 67668B06 mov (%esi), %eax
10
11 .code32
12 main32:
13 000c 67668B04 mov (%si), %ax
14 0010 678B04 mov (%si), %eax
15 0013 668B06 mov (%esi), %ax
16 0016 8B06 mov (%esi), %eax
17
18 .code64
19 main64:
20 // mov (%si), %ax
21 // mov (%si), %eax
22 // mov (%si), %rax
23 0018 67668B06 mov (%esi), %ax
24 001c 678B06 mov (%esi), %eax
25 001f 67488B06 mov (%esi), %rax
26 0023 668B06 mov (%rsi), %ax
27 0026 8B06 mov (%rsi), %eax
28 0028 488B06 mov (%rsi), %rax
29
GAS LISTING test.s page 2
DEFINED SYMBOLS
*ABS*:0000000000000000 test.s
test.s:5 .text:0000000000000000 main16
test.s:12 .text:000000000000000c main32
test.s:19 .text:0000000000000018 main64
NO UNDEFINED SYMBOLS
ここで気が付くのは、同じ命令でも、違うコードが出ている。
例えば、
mov (%esi), %eax
は
16bitでは、67668B06
32bitでは、8B06
64bitでは、678B06
となっている。
67というのは、アドレスサイズプレフィックス
66というのは、オペランドサイズプレフィックス
これを見ると、各モードで、最も命令コードが短くなるアドレスサイズ、オペランドサイズが決まっているように見える。
16bitモードでは、アドレスサイズ、オペランドサイズが16bitが基本。
67を付けるとアドレスサイズが32bitになる。
66を付けるとオペランドサイズが32bitになる。
32bitモードでは、アドレスサイズ、オペランドサイズが32bitが基本。
67を付けるとアドレスサイズが16bitになる。
66を付けるとオペランドサイズが16bitになる。
64bitモードでは、アドレスサイズ64bit、オペランドサイズ32bitが基本。
67を付けるとアドレスサイズが16bitになる。
66を付けるとオペランドサイズが16bitになる。
48を付けるとオペランドサイズが64bitになる。
以下の表はアドレスサイズとオペランドサイズのbit幅に対し、どのようなプレフィックスを付ければいいのかを表している。
Mode
Addr Data 16bit 32bit 64bit
Mode
Addr Data 16bit 32bit 64bit
16 16 なし 6766 不可
16 32 66 67 不可16 64 不可 不可 不可
32 16 67 66 6766
32 32 6766 なし 67
32 64 不可 不可 6748
64 16 不可 不可 66
64 32 不可 不可 なし
64 64 不可 不可 48