带/参数的函数调用
Function calling w/ parameters
我正在努力创建函数并在程序集中调用它们。
函数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
add esp, 16
因为这是 16 位代码,将 4 个参数压入堆栈只需要弹出 8 个字节。
gfx_draw_h:
pop ax ; color
pop cx ; x
pop dx ; y
因为 gfx_draw_h 是一个子例程(它被 call
ed)所以在堆栈上有一个 return 地址。您的第一个 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 !!!
我正在努力创建函数并在程序集中调用它们。
函数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
add esp, 16
因为这是 16 位代码,将 4 个参数压入堆栈只需要弹出 8 个字节。
gfx_draw_h:
pop ax ; color
pop cx ; x
pop dx ; y
因为 gfx_draw_h 是一个子例程(它被 call
ed)所以在堆栈上有一个 return 地址。您的第一个 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 !!!