我目前正在重新编写NASM x64中标准C库中的一些函数.目前我只有两项职能:
strlen:
bits 64
section .text
global strlen
strlen:
xor rbx, rbx
jmp strlen_loop
strlen_loop:
cmp byte [rdi + rbx], 0
je strlen_ret
inc rbx
jmp strlen_loop
strlen_ret:
mov rax, rbx
ret
putstr:
bits 64
extern strlen
STDOUT equ 1
section .text
global putstr
putstr:
call strlen
mov rdx, rax
xor rax, rax
mov rdi, STDOUT
syscall
ret
以下是生成文件:
CC = nasm
CFLAGS = -f elf64
SRC = $(wildcard src/*.asm)
OBJ = $(SRC:.asm=.o)
NAME = minilibc.so
all: $(NAME)
$(NAME): $(OBJ)
ld -fPIC -shared -o $(NAME) $(OBJ) -nostdlib
%.o: %.asm
$(CC) $(CFLAGS) $< -o $@
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all
test: re
gcc -o test/test test/main.c
LD_PRELOAD=./minilibc.so ./test/test
.PHONY: all clean fclean re
以及测试代码:
#include <stdio.h>
extern size_t putstr(const char *str);
int main(void)
{
const char *str = "Hello, World!\n";
putstr(str);
return (0);
}
下面是我得到的错误:
rm -f src/putstr.o src/strlen.o rm -f minilibc.so nasm -f elf64 src/putstr.asm -o src/putstr.o nasm -f elf64 src/strlen.asm -o src/strlen.o ld -fPIC -shared -o minilibc.so src/putstr.o src/strlen.o -nostdlib ld: src/putstr.o: attention: readdress on "strlen" in read-only ".text" section ld: src/putstr.o: readdressing R_X86_64_PC32 to symbol "strlen" cannot be used when creating a shared object; recompile with -fPIC ld: final link edit failed: wrong value make: *** [Makefile:10: minilibc.so] Error 1
LD似乎在告诉我在PIC模式下重新编译,我已经在这样做了,那么我的函数与GLIBC函数同名是不是有问题?但是,我在没有标准库的情况下进行编译.