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 <stdio.h>
 
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)