所以我最近再次轉向 nasm 并嘗試構建一些基本的東西(putc 和 puts)。
Putc作業正常,但問題是在我呼叫putcin 之后puts,retinputc不會回傳到ip推入堆疊的狀態puts,因此沒有更多的指令被執行puts(在 gdb 中除錯該部分)。
msg db "Welcome!", 0ah, 0dh, 0h
putc:
push ebp
mov esp, ebp
mov ah, 0ah
; al is set before
mov bh, 0
mov bl, 0
mov cx, 1
int 10h
ret
puts:
push ebp
mov esp, ebp
mov ebx, msg
dec ebx
puts_l:
inc ebx
mov al, [ebx]
call putc
cmp al, 0h
jne puts_l
ret
這顯然不是最好的,但我想我在某處有誤解。我可以想象一個暫存器會被 putc 覆寫,但這并不能說明為什么retin putc 不回傳puts
我還應該提到我正在使用 x86。
uj5u.com熱心網友回復:
當你做
push ebp
mov esp, ebp
esp不再指向推送ebp和回傳地址,這是在函式結尾中使用LEAVE無法解決的問題。順便說一句,LEAVE應該與ENTER配對。
如果你真的需要堆疊幀(例如定義一個本地記憶體變數),框架可能看起來像這樣:
Function:
PUSH EBP
MOV EBP,ESP
SUB ESP,4 ; The local variable is now addressable as [ESP] alias [EBP-4].
; Here is the Function body which can use local variable(s).
MOV ESP,EBP ; Discard local variable, ESP will point to the saved EBP.
POP EBP ; Restore EBP which might be used as parent's frame pointer.
RET
由于您的程式不使用區域變數,因此可能是
mov esi, msg ; Address of the ASCIIZ string.
call puts
jmp $ ; Program ends here.
puts: ; Function which displays ASCIIZ string at ESI.
lodsb ; Load AL from [DS:ESI], increment ESI.
cmp al, 0h
je puts_2
call putc ; Display a nonzero character in AL.
jmp puts
puts_2: ret
putc: ; Function which displays a character in AL.
mov ah, 0ah ; WRITE CHARACTER.
mov bh, 0 ; Videopage 0.
mov bl, 0 ; Colour in graphic mode.
mov cx, 1 ; Number of times to write character
int 10h ; Invoke BIOS videofunction.
ret
msg db "Welcome!", 0ah, 0dh, 0h ; The displayed ASCIIZ string.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384834.html
