为清楚起见添加了实际代码,对不起,我是开发PC上的AFK。在出现问题的标记为XXXX的行中,如果直接使用标签,则可以访问wiseman的值,但是如果尝试从堆栈中访问标签的值,则不能。
stage2: ; stage 2 bootloader
push 50 ; y
push 50 ; x
push 06h ; first color, brown
push 0Ch ; second color, red
push wiseman ; sprite to draw
push 32 ; how many bytes the sprite has
call draw_sprite
cli
hlt
; 00 is always black and 11 is always white
draw_sprite:
push bp ; save old base pointer
mov bp, sp ; use the current stack pointer as new base pointer
pusha
mov cx, [bp + 12] ; x coordinate
mov dx, [bp + 14] ; y coordinate
; initializing to 0, saves one byte from using mov
xor si, si ; index of the bit we are checking (width)
xor di, di
.row: ; main loop, this will iterate over every bit of [rock], if it is a 1 the .one part will be executed, if it is a 0 the .zero part will
cmp si, 16 ; check if we have to move to the next byte/row
jne .same_row ; Byte checked
xor si, si ; this executes if we move to the next row
add di, 2 ; next row
cmp di, [bp + 4] ; if we have finished with the tile
je .done
inc dx
mov cx, [bp + 12] ; x coordinate
.same_row:
xor bh, bh ; store the color
mov ax, [wiseman + di] ;XXXXXXX works with wiseman + di but no with bp + 6 + di
bt ax, si ; first bit
jnc .next_bit
add bh, 1
.next_bit:
inc si
bt ax, si ; second bit
jnc .end_bit
add bh, 2
.end_bit:
cmp bh, 0 ; black
je .pass
cmp bh, 1 ; first_color
je .first_color
cmp bh, 2 ; second_color
je .second_color
cmp bh, 3 ; white
je .white
.first_color:
; draw
mov ah, 0Ch
xor bh, bh
mov al, [bp + 10]
int 10h
jmp .pass
.second_color:
; draw
mov ah, 0Ch
xor bh, bh
mov al, [bp + 8]
int 10h
jmp .pass
.white:
; draw
mov ah, 0Ch
xor bh, bh
mov al, 0Fh
int 10h
jmp .pass
.pass:
inc si
inc cx
jmp .row
.done:
popa
mov sp, bp
pop bp
ret 12
wiseman: dw 0x5400, 0x7700, 0x4500, 0x4500, 0x5E00, 0xFF80, 0x0FA0, 0xFBE8, 0xFAE9, 0xFAA9, 0xE8A9, 0xA8A8, 0xA8A8, 0xAA20, 0xAA00, 0x9680 ; 32 bytes
我想我有一个解决的问题,但是我不完全明白为什么。
答案 0 :(得分:0)
最后,我解决了不同的问题,因为我无法通过其他方式使它工作:
stage2:
mov cx, 32
lea di, [current_sprite]
lea si, [wiseman_left]
rep movsb
push 90 ; y
push 144 ; x
push 06h ; first color, brown
push 0Ch ; second color, red
push 32 ; how many bytes the sprite has
call draw_sprite
cli
hlt
00 is always black and 11 is always white
raw_sprite:
push bp ; save old base pointer
mov bp, sp ; use the current stack pointer as new base pointer
pusha
mov cx, [bp + 10] ; x coordinate
mov dx, [bp + 12] ; y coordinate
; initializing to 0, saves one byte from using mov
xor si, si ; index of the bit we are checking (width)
xor di, di
row: ; main loop, this will iterate over every bit of [rock], if it is a 1 the .one part will be executed, if it is a 0 the .zero part will
cmp si, 16 ; check if we have to move to the next byte/row
jne .same_row ; Byte checked
xor si, si ; this executes if we move to the next row
add di, 2 ; next row
cmp di, [bp + 4] ; if we have finished with the tile
je .done
inc dx
mov cx, [bp + 10] ; x coordinate
same_row:
xor bh, bh ; store the color
mov ax, [current_sprite + di]
bt ax, si ; first bit
jnc .next_bit
add bh, 1
next_bit:
inc si
bt ax, si ; second bit
jnc .end_bit
add bh, 2
end_bit:
cmp bh, 0 ; black
je .pass
cmp bh, 1 ; first_color
je .first_color
cmp bh, 2 ; second_color
je .second_color
cmp bh, 3 ; white
je .white
first_color:
; draw
mov ah, 0Ch
xor bh, bh
mov al, [bp + 8]
int 10h
jmp .pass
second_color:
; draw
mov ah, 0Ch
xor bh, bh
mov al, [bp + 6]
int 10h
jmp .pass
white:
; draw
mov ah, 0Ch
xor bh, bh
mov al, 0Fh
int 10h
jmp .pass
pass:
inc si
inc cx
jmp .row
done:
popa
mov sp, bp
pop bp
ret 10
current_sprite: dw 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000; 44 bytes
wiseman_left: dw 0x5400, 0x7700, 0x4500, 0x4500, 0x5E00, 0xFF80, 0x0FA0, 0xFBE8, 0xFAE9, 0xFAA9, 0xE8A9, 0xA8A8, 0xA8A8, 0xAA20, 0xAA00, 0x9680 ; 32 bytes
我只是将当前的精灵复制到一个内存位置中以供访问。