访问x86中存储在堆栈中的标签

时间:2019-03-08 03:06:13

标签: assembly x86 nasm bootloader

为清楚起见添加了实际代码,对不起,我是开发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

我想我有一个解决的问题,但是我不完全明白为什么。

1 个答案:

答案 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

我只是将当前的精灵复制到一个内存位置中以供访问。