5

再次对不起。我正在尝试了解学习汇编语言。但是我有很多问题。我正在尝试在 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  

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

4

2 回答 2

2

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

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

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

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

于 2013-11-05T20:15:49.430 回答
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),但我想让它接近你的实现。

希望这可以帮助!

于 2013-11-05T20:40:26.397 回答