Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strlen in NASM Linux

Excuse me again. I am trying understand learn assembly languaje. However I have many problems. I am trying working with strings in NASM. I have copy a string constant to string variable. The maximum size is 50. So I want verify this bound. However this program throw a segmentation fault. I use a example in MASM, so perhaps exist a use error with NASM syntax. My program is the following:

section .data                                                                                                                    
   MAXTEXTSIZE equ 50
   _cte_hola db "Hola", 0
   _cte_mundo db "Mundo", 0

section .bss
   MAIN_d resb MAXTEXTSIZE+1

section .text
      global _start

strlen:
  mov bx, 0
  strl01:
  cmp WORD [SI+BX],0 t
  je strend 
  inc bx 
  jmp strl01
strend:
  ret

strcpy:
   call strlen 
   cmp bx, MAXTEXTSIZE 
   jle copiarsizeok    
   mov bx, MAXTEXTSIZE
copiarsizeok:mov cx, bx
   cld 
   rep movsb 
   mov al,0 
   mov BYTE [DI], al
   ret


_start:
  mov ds, ax
  mov es, ax
  mov si, [MAIN_d]
  mov di, [_cte_hola]
  call strcpy
  mov eax, 1
  mov ebx, 0
  int 80h  

Thanks in advance and excuse me. My question are stupid for a assembly programmer.

like image 783
maxiperez Avatar asked Oct 03 '22 12:10

maxiperez


2 Answers

I believe you are trying to make 32bit program in Linux, but your examples are 16bit.

  1. In Linux, all pointers are 32bit. So, use extended registers: esi, edi, ebx etc. You still can use 8 and 16bit registers for arithmetics and data processing but not as memory pointers.

  2. In strlen you have to compare byte [esi+ebx], 0 not word.

  3. Don't set the segment registers in Linux. They will be set by the OS and you can't touch them. In Linux all memory is one flat area and you don't have to use segment registers anymore.

like image 105
johnfound Avatar answered Oct 05 '22 12:10

johnfound


Here's a more concrete example of how you could write your strlen function (which is the first of your problems)

section .data
  MAXTEXTSIZE equ 50
  _cte_hola  db "Hola",  0xa, 0
  _cte_mundo db "Mundo", 0

section .bss
  MAIN_d resb MAXTEXTSIZE+1

section .text
  global _start

strlen:
  mov ebx, 0
strlen_loop:
  cmp BYTE [esi+ebx], 0
  je strlen_end
  inc ebx
  jmp strlen_loop
strlen_end:
  mov eax, ebx
  ret

_start:
  mov esi, _cte_hola
  call strlen ; Get the length of _cte_hola

  mov edx, eax ; The length was stored in eax by strlen
  mov ecx, _cte_hola
  mov ebx,1
  mov eax, 4
  int 0x80 ; Write to stdout

  mov eax, 1
  int 0x80 ; Exit

There are definitely better ways of implementing this (I'd use repne to implement strlen, for example) but I wanted to keep it close to your implementation.

Hope this helps!

like image 26
Alex Reinking Avatar answered Oct 05 '22 12:10

Alex Reinking