I am reading "Introduction to 64 Bit Intel Assembly Language Programming for Linux" and porting the code to Windows using Yasm and MS Visual Studio 2013 for learning reasons. At chapter 7, there is an example of 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
And I got from linker:
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
However, I tried to figured out what's going on and I understand it's some addressing problem on x64 architecture. So I changed my code to:
mov rax, [qword i]
lea rbx, [rel switch]
imul rax, 0x8
add rbx, rax
jmp [rbx]
And the code worked. But, I have a question: this code is supposed to work on Linux using gcc or ld as linker. Why did i need to modify the code?