gpt4 book ai didi

linux - NASM 你能解释一下为什么我的代码会返回一个段错误吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:05:45 58 4
gpt4 key购买 nike

我的代码在第二次调用子例程 prntlf 时返回段错误。

_start:
mov ecx, msg
call prntlf

call prntlf ; Here is where the issue is

经过实验,我发现只有当我没有将 ecx 的值设置回我想要它打印的字符串时才会发生,但我想知道的是为什么我必须去做。鉴于我从保存的堆栈中弹出了寄存器的值,ecx 不应该仍然保留要打印的有效字符串吗?

完整来源:

文件hello.asm:

; RUN WITH `nasm -f elf32 hello.asm -o hello.o && ld -m elf_i386 hello.o -o hello && ./hello`

%include 'subroutines.inc'

section .data
msg db "Hello, World!", 0x0
msg2 db "Goodbye, Moon!", 0x0
linefeed db 0xA, 0xD

section .text
global _start:

_start:
mov ecx, msg
call prntlf

call prntlf

jmp end

文件:subroutines.inc

    ; subroutines.inc


;===============================================================================
; getstrlen | Gets String Length and pushes the value to register edx
;===============================================================================
getstrlen:
push eax
push ebx
mov eax, ebx

findnterm:
cmp byte [eax], 0
jz gotstrlen
inc eax
jmp findnterm

gotstrlen:
sub eax, ebx
mov edx, eax
pop eax
pop ebx
ret

;===============================================================================
; printstr | Prints a String using a dynamic algorithm to find null terminator
;===============================================================================
printstr:
push eax
push ebx
push edx

mov ebx, ecx
call getstrlen

mov ebx, 0x01
mov eax, 0x04
int 0x80

pop eax
pop ebx
pop edx
ret

;===============================================================================
; prntlf | Prints a String and appends a Linefeed.
;===============================================================================
prntlf:
push eax
push ebx
push ecx
push edx

mov eax, ecx

movetoendloop:
cmp byte [eax], 0
jz donemoving
inc eax
jmp movetoendloop

donemoving:
call printstr
mov ecx, linefeed
call printstr

pop eax
pop ebx
pop ecx
pop edx
ret

;===============================================================================
; end | calls kernel and tells it to End the program
;===============================================================================
end:
mov eax, 0x01
mov ebx, 0x00
int 0x80

最佳答案

堆栈是后进先出的结构,这意味着无论您将其弹出到哪个寄存器,您最后压入堆栈的东西都会最先弹出。

prntlf:
push eax
push ebx
push ecx
push edx

...

pop edx ; Pop them back from the stack in the reverse order in which you pushed them.
pop ecx
pop ebx
pop eax
ret

关于linux - NASM 你能解释一下为什么我的代码会返回一个段错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47060568/

58 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com