strlen in NASM Linux

时间:2013-11-05 19:50:05

标签: linux assembly x86 nasm

再次打扰一下。我正在努力了解学习集会语言。但是我有很多问题。我正在尝试使用NASM中的字符串。我已将字符串常量复制到字符串变量。最大大小为50.所以我想验证这个绑定。但是这个程序会引发分段错误。我在MASM中使用了一个示例,因此可能存在使用NASM语法的使用错误。 我的计划如下:

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  

提前谢谢,对不起。我的问题对于汇编程序员来说是愚蠢的。

2 个答案:

答案 0 :(得分:2)

我相信您正在尝试在Linux中制作32位程序,但您的示例是16位。

  1. 在Linux中,所有指针都是32位。因此,使用扩展寄存器:esi,edi,ebx等。您仍然可以使用8位和16位寄存器进行算术和数据处理,但不能用作存储器指针。

  2. 在strlen中,你必须比较byte [esi+ebx], 0而不是单词。

  3. 不要在Linux中设置段寄存器。它们将由操作系统设置,您无法触摸它们。在Linux中,所有内存都是一个平面区域,您不必再使用段寄存器了。

答案 1 :(得分:2)

这是一个更具体的例子,说明如何编写strlen函数(这是你的第一个问题)

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

肯定有更好的方法来实现这一点(例如,我使用repne来实现strlen)但我想让它与您的实现保持接近。

希望这有帮助!