「Linux 用の 64 ビット Intel アセンブリ言語プログラミングの概要」を読み、学習のために Yasm と MS Visual Studio 2013 を使用してコードを Windows に移植しています。第 7 章に、switch の例があります。
global _tmain
segment .data
switch: dq _tmain.case0
dq _tmain.case1
dq _tmain.case2
i: dq 1
segment .text
_tmain:
mov rax, [qword i]
jmp [switch+rax*8]
.case0:
mov rbx, 100
jmp .end
.case1:
mov rbx, 101
jmp .end
.case2:
mov rbx, 102
.end:
xor rax, rax
ret
そして、リンカーから取得しました:
Microsoft (R) Incremental Linker Version 12.00.30501.0
Copyright (C) Microsoft Corporation. All rights reserved.
switch2.obj : error LNK2017: 'ADDR32' relocation to 'switch' invalid without /LARGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
ただし、何が起こっているのかを理解しようとしましたが、x64 アーキテクチャのアドレス指定の問題であることを理解しています。だから私は自分のコードを次のように変更しました:
mov rax, [qword i]
lea rbx, [rel switch]
imul rax, 0x8
add rbx, rax
jmp [rbx]
そして、コードは機能しました。しかし、質問があります。このコードは、リンカーとして gcc または ld を使用して Linux で動作するはずです。なぜコードを変更する必要があったのですか?