我正在阅读“Linux 的 64 位英特尔汇编语言编程简介”并出于学习原因使用 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 上运行。为什么我需要修改代码?