====== String-Funktionen der C-Standardbibliothek in NASM ======
===== Implementierung =====
==== NASM ====
; string.asm
section .text
; Funktionen müssen global sein, damit sie aus C aufgerufen werden können.
global asm_strcpy, asm_strncpy, asm_strcat, asm_strncat, asm_strlen
; void asm_strcpy( char *dst, char *src );
; rdi = dst
; rsi = src
asm_strcpy:
xor rax, rax
.loop:
mov al, [rsi]
mov [rdi], al
inc rdi
inc rsi
cmp rax, 0x0
jnz .loop
ret
; void asm_strncpy( char *dst, char *src, int size );
; rdi = dst
; rsi = src
; rbx = size
asm_strncpy:
mov rcx, rdx
rep movsb
ret
; void asm_strcat( char *dst, char *src );
; rdi = dst
; rsi = src
asm_strcat:
cmp byte [rdi], 0x0
jz .copy
.loop:
inc rdi
cmp byte [rdi], 0x0
jnz .loop
.copy:
call asm_strcpy
ret
; void asm_strncat( char *dst, char *src, int size );
; rdi = dst
; rsi = src
; rbx = size
asm_strncat:
cmp byte [rdi], 0x0
jz .copy
.loop:
inc rdi
cmp byte [rdi], 0x0
jnz .loop
.copy:
call asm_strncpy
ret
; int asm_strlen( char *str );
; rdi = str
; rax = return value
asm_strlen:
xor rax, rax
cmp byte [rdi], 0x0
jz .end
mov rdx, rdi
.loop:
inc rdi
cmp byte [rdi], 0x0
jnz .loop
mov rax, rdi
sub rax, rdx
.end:
ret
==== C ====
// main.c
#include
extern void asm_strcpy( char *dst, char *src );
extern void asm_strncpy( char *dst, char *src, int size );
extern void asm_strcat( char *dst, char *src );
extern void asm_strncat( char *dst, char *src, int size );
extern int asm_strlen( char *str );
int main()
{
char src[] = "test";
char dst[9] = { '\0' };
printf( "%s (%p, %d) - %s (%p, %d)\n", src, src, asm_strlen( src ), dst, dst, asm_strlen( dst ) );
asm_strcpy( dst, "asdf" );
asm_strncat( dst, src, 3 );
printf( "%s (%p, %d) - %s (%p, %d)\n", src, src, asm_strlen( src ), dst, dst, asm_strlen( dst ) );
return 0;
}
===== Kompilieren und Linken =====
==== Manuell ====
$ nasm -f elf64 string.asm -g -F stabs
$ gcc -o test string.o main.c -g -Wall
==== Makefile ====
asmstring: string.o main.o
gcc -o asmstring string.o main.o
string.o: string.asm
nasm -f elf64 -g -F stabs string.asm
main.o: main.c
gcc -c main.c
:!: **Achtung:** Zum Einrücken müssen Tabs verwendet werden!
===== Ausgabe =====
$ ./asmstring
test (0x7fffbb8340d0, 4) - (0x7fffbb8340c0, 0)
test (0x7fffbb8340d0, 4) - asdftes (0x7fffbb8340c0, 7)