I am writing a project in x86-64 Assembly and I want to write an efficient switch statement using a branch lookup table. However, I get position independence errors.
I'll start with my code. The assembly was taken from this answer.
Assembly:
global mySwitch
section .text
mySwitch:
jmp [.jump_table + 2 * edi]
.jump_table: dw .one, .two
.one:
mov eax, 123
ret
.two:
mov eax, 321
ret
C:
#include <stdio.h>
int mySwitch(int arg);
int main() {
printf("%d\n", mySwitch(1));
}
I am trying to compile it with the following commands:
nasm -f elf64 -w+all -w+error switch.asm -o switch_asm.o
gcc -c -Wall -Wextra -std=c17 -O2 switch.c -o switch_c.o
gcc switch_asm.o switch_c.o -o switch
but the third one returns the following error:
/usr/bin/ld: switch_asm.o: relocation R_X86_64_32 against `.text' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
make: *** [makefile:4: all] Error 1
Using the -fPIE
switch is against the rules of the assignment (and also does not help), and I do not know what I am missing (previously, the problem was caused by a missing rel
or wrt ..plt
).
Update:
Changing my assembly code slightly to 64-bit addresses and a lea
instruction like so:
lea rax, [rel .jump_table]
jmp [rax + rdi * 8]
.jump_table: dq .one, .two
compiles, and works as expected. I'd love to post this is an answer as to how to write a switch statement in asm but I cannot because this question is closed due to being a duplicate despite not being a duplicate so oh well.