您好,我正在尝试学习汇编(NASM)。我在那里观看了一些视频,现在我正在尝试编写一些代码。该代码是获取一个字符串并计算它的长度,然后将其传递给系统调用并打印它。但它在打印“Hello World!”后立即出现分段错误。其他字符串不再打印。
这是我的代码:
section .data
msg db "Hello World!",0
msg2 db "Good Bye World",0
msg3 db "Hello Universe",0
section .text
global _start
_strlen:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov bl, [eax]
mov ecx, 0
_loop:
cmp bl, 0
je _loopend
add eax, 1
mov bl, [eax]
add ecx, 1
jmp _loop
_loopend:
mov eax, ecx
xor ebx, ebx
xor ecx, ecx
pop ebp
ret
_printstr:
push ebp
mov ebp, esp
mov eax, [ebp+8]
push eax
call _strlen
mov edx, eax
mov eax, 4
mov ebx, 1
mov ecx, [ebp+8]
int 80h
pop ebp
ret
_start:
push msg
call _printstr
push msg2
call _printstr
push msg3
call _printstr
mov ebx, 0
mov eax, 1
int 80h
在
_printstr
中,您将 eax
压入堆栈以供 _strlen
使用,但随后无法再次将其弹出。 这会导致 _printstr
返回某个随机地址,而不是正确的返回地址。
确保在函数返回时弹出压入堆栈的所有内容。 您还可以使用这样的堆栈框架设置:
push ebp ; push old ebp
mov ebp, esp ; set up new ebp
...
leave ; short for "mov esp, ebp; pop ebp"
ret
即使您忘记从堆栈中弹出一些内容,此设置也可以工作,并且对于人工编写的代码来说非常方便。