As the question mentions i am trying to link an .a library with an .asm file. I am using Ubuntu, nasm and gcc for doing so with the following MRE and commands:
nasm -f elf64 -o use.o use.asm
nasm -f elf64 -o strlen.o strlen.asm
ar rc libstring.a strlen.o
ranlib libstring.a
ld -static -nostdlib -build-id=none -L. -lstring -o use.bin use.o
The used files look like this: strlen.asm:
BITS 64
GLOBAL strlen
;-------------------------------------------------------------------------------
; @func strlen
;
; @params String str
;
; @returns uint_32 length
;-------------------------------------------------------------------------------
strlen:
push rcx
push rsi
xor eax, eax
xor ecx, ecx
mov rsi, [rsp + 0x10]
jmp .foreach
.inc_i:
inc ecx
.foreach:
lodsb
or al, al
jnz .inc_i
.return:
mov eax, ecx
pop rsi
pop rcx
ret
use.asm:
BITS 64
GLOBAL _start
EXTERN strlen
_start:
push str
call strlen
cli
hlt
str: DB "String!", 0x00
I do NOT expect them to do something, they should just compile. Currently the linker gives this error:
ld: use.o: in function `_start':
use.asm:(.text+0x6): undefined reference to `strlen'
Since the error does not mention that the file could not be found, i guess the naming convention of .a files is correct. But why does it not find the method then?
In order to solve this, one has to order the -L and -l flags in a way, they are placed after the files which require them. When using multiple libraries in different locations, one has to make sure the repositioning doesn't misposition the -L flag(s), that could cause some trouble aswell.
So in this MRE, the ld command should look like this:
ld -static -nostdlib -build-id=none use.o -L . -l string -o use.bin
Also don't forget to sudo chmod +x make.sh
when using a bash script to compile, that might give you 5 minutes of head scratching ^^