2015-10-04 73 views
2

我很努力地創建函數並在彙編中調用它們。帶參數的函數調用

功能gfx_draw_h(color, x_1, y_1, x_2)應借鑑(x_1, y_1)(x_2, y_1)一條線,但我不能得到x_2值與內部gfx_draw_h.repeat當前位置進行比較。

另外,是另一段代碼是否正確(沒有堆棧損壞)?

這是我的代碼:

BITS 16 

; ---------------------------------------------------------------------- 

_start: 
    mov ax, 07C0h 
    add ax, 288 
    mov ss, ax    ; SS = stack space 
    mov sp, 4096   ; SP = stack pointer 

    mov ax, 07C0h 
    mov ds, ax    ; DS = data segment 

    call gfx_init 

    push 50     ; x_2 
    push 30     ; y_1 
    push 30     ; x_1 
    push 1000b    ; color 

    call gfx_draw_h 

    add esp, 16 

    jmp $     ; infinite loop 

; ---------------------------------------------------------------------- 
; Initializes graphics. 
; 
; Sets the video mode. 
; 
; INPUT: 
; none 
; 
; OUTPUT: 
; none 
; 
gfx_init: 
    mov ah, 00h    ; set video mode 
    mov al, 12h    ; AL = graphical mode 
    int 10h     ; INT 10h/AH = 00h 
    ret 

; ---------------------------------------------------------------------- 
; Draws a horizontal line. 
; 
; INPUT: 
; color 
; x_1 
; y_1 
; x_2 
; 
; OUTPUT: 
; none 
; 
gfx_draw_h: 
    pop ax     ; color 
    pop cx     ; x 
    pop dx     ; y 

    mov ah, 0Ch    ; change color for a single pixel 

.repeat: 
    cmp cx, [ebp + 20]  ; !!! THIS IS THE ISSUE !!! 
    je .done 

    inc cx 
    int 10h 

    jmp .repeat 

.done: 
    ret 

; ---------------------------------------------------------------------- 

times 510 - ($ - $$) db 0 ; padding with 0 at the end 
dw 0xAA55     ; PC boot signature 

回答

2
add esp, 16 

由於這是16位代碼堆棧將只需要你爆開8個字節推4個參數。

gfx_draw_h: 
pop ax     ; color 
pop cx     ; x 
pop dx     ; y 

由於gfx_draw_h是一個子程序(這是call ED)有堆棧上的返回地址。你的第一個pop ax消除了這個!你可以寫:

gfx_draw_h: 
mov bp, sp 
mov ax, [bp+2] ;color 
mov cx, [bp+4] ;x 
mov dx, [bp+6] ;y 

按照這一邏輯改變問題這樣一行(不使用EBP!):

cmp cx, [bp + 8]  ; !!! THIS IS THE ISSUE !!! 
+0

你忘了用'sp'覆蓋它之前'推bp' 。現代調試器根本不需要堆棧,所以你可以跳過那部分,特別是。對於沒有修改'sp'的葉函數。 –

+0

@PeterCordes我沒有真正忘記'push bp',但試圖儘可能簡單。並且由於OP不在意推送任何寄存器... –

+0

@ user3144770謝謝!我明白我以前做錯了什麼。 @PeterCordes我應該推「bp」的原因是什麼?我在'ret'之前的'mov bp,sp'和'pop bp'之前加了'push bp'。這是你在說什麼嗎? – user5406450