【问题标题】:how to load more sector and call a function in the loaded sector如何加载更多扇区并在加载的扇区中调用函数
【发布时间】:2013-11-24 09:17:16
【问题描述】:

我用

组装了以下代码 nasm -f bin 选项

并放入软盘镜像,然后用virtualbox运行

我的目标是call print_word

但是我怎么能在这里call print_word

要了解如何调用额外扇区中的函数,

我将print_word 放入有内涵的第二扇区。

提前致谢。

main.asm:

org 0x7c00
start:
    mov ax, 0x0206
    mov cx, 0x0002
    mov dx, 0x0000

    mov bx, 0x7e00
    push bx
    pop es

    mov bx, 0
.try_again:
    int 13h
    jc .try_again

    mov ax, 0xabcd
    push ax
    jmp 0x7e00


jmp $

times 510 - ($-$$) db 0
dw 0xaa55

more:
    %include "./common/print_word.asm"

print_word.asm:

;print_word(word)
print_word:
    push bp
    mov bp, sp

    push word [bp+4]
    call print_word_1

    push word [bp+4]
    call print_word_2
    push word [bp+4]
    call print_word_3
    push word [bp+4]
    call print_word_4
    mov sp, bp
    pop bp
    ret


print_word_1:
    push bp
    mov bp, sp

    mov ah, 0x0e
    mov byte al, [bp+4]
    shr al, 4
    cmp al, 0x0a
    jl .num
    sub al, 0x0a
    jmp .char
.num:
    add al, '0' 
    jmp .put
.char:
    add al, 'A'
    jmp .put
.put:
    int 10h
    mov sp, bp
    pop bp
    ret

print_word_2:
    push bp
    mov bp, sp

    mov ah, 0x0e
    mov byte al, [bp+4]
    shl al, 4
    shr al, 4
    cmp al, 0x0a
    jl .num
    sub al, 0x0a
    jmp .char
.num:
    add al, '0' 
    jmp .put
.char:
    add al, 'A'
    jmp .put
.put:
    int 10h
    mov sp, bp
    pop bp
    ret


print_word_3:
    push bp
    mov bp, sp

    mov ah, 0x0e
    mov byte al, [bp+5]
    shr al, 4
    cmp al, 0x0a
    jl .num
    sub al, 0x0a
    jmp .char
.num:
    add al, '0' 
    jmp .put
.char:
    add al, 'A'
    jmp .put
.put:
    int 10h
    mov sp, bp
    pop bp
    ret

print_word_4:
    push bp
    mov bp, sp

    mov ah, 0x0e
    mov byte al, [bp+5]
    shl al, 4
    shr al, 4
    cmp al, 0x0a
    jl .num
    sub al, 0x0a
    jmp .char
.num:
    add al, '0' 
    jmp .put
.char:
    add al, 'A'
    jmp .put
.put:
    int 10h
    mov sp, bp
    pop bp
    ret

【问题讨论】:

    标签: assembly x86 nasm bootloader bios


    【解决方案1】:

    使用常规的 CALL 指令。您的汇编器将汇编一个带有位移而不是绝对地址的 CALL NEAR。像这样的:

    mov ax,0xabcd
    push ax
    call print_word
    add sp,2  ;to restore the stack
    
    jmp $
    

    另外,请注意您的print_word routine,在调用print_word_1print_word_2 等时,不会正确恢复堆栈。您的调用约定要求调用者删除它压入堆栈的参数,因此在每个call print_word_N 指令之后,您必须通过发出add sp,2 指令或将最后一个堆栈元素弹出到未使用的登记。例如,像这样:

    由于传递给不同 print_word_N 例程的值始终相同,并且您的例程不会更改参数的值,因此您可以通过假设参数已经在堆栈上第二次来稍微优化代码大小以及后续调用:

    print_word:
        push bp
        mov bp, sp
    
        push word [bp+4]
        call print_word_1
        call print_word_2
        call print_word_3
        call print_word_4
        mov sp, bp
        pop bp
        ret
    

    顺便说一句:别忘了这是一个小端机器。您正在转换为十六进制并打印[ebp+4] 处的字节,然后打印[ebp+5] 处的字节。这将导致CDAB 打印在屏幕上。十六进制数的最左侧两位数字位于 [ebp+5] 的字节中,因此您应该先打印它们,然后再将数字存储在字节 [ebp+4] 中。

    啊!关于加载扇区:您的错误是您如何考虑加载扇区的块的段和偏移量。您希望在 0000:7E00 加载下一个扇区,即加载的前 512 个字节代码旁边。相反,您在 7E00:0000 加载它,这根本不是同一个地址。

    更新修复的代码如下(加载下一个扇区的部分):

    org 0x7c00
    start:
        mov ax, 0   ;segment is 0
        mov ds, ax
        mov es, ax
    
    .try_again:
        mov ax, 0x0201  ;load 1 sector
        mov cx, 0x0002  ;located at sector 2
        mov dx, 0x0000
        mov bx, 0x7e00  ;into 0000:7E00
        int 13h
        jnc .ok
    .errorsector:
        mov ax,0   ;reset floppy controller ir error
        int 13h
        jmp .try_again
    
    .ok:
        mov ax, 0xabcd
        push ax
        call print_word
        add sp,2
    
        jmp $
    

    【讨论】:

    • 非常感谢您的回复,我试过调用 print_word,调用 0x7e00,jmp print_word,调用 es:print_word。没有打印字母,但显示空白屏幕或出错。你能给我更多的信息吗?
    • 有一个简短的例子真的很好。读取一个扇区并在加载的扇区上调用函数的示例
    • 关于在加载的扇区上调用函数,我刚刚提供了。问题似乎出在实际的扇区加载中。如果我将 print_word 例程移到第一个扇区,它会按预期工作。
    • 我发现您的扇区加载代码有什么问题。检查更新的答案。
    • 非常感谢!将 es 设置为 0 并将 bx 设置为 0x7e00 后,它可以工作了!但我仍然不明白你为什么将 ds 设置为 0。再加上一个,我尝试将 bx 设置为 0x8e00, 0x9e00 但它仍然有效,我想知道为什么。还是谢谢
    猜你喜欢
    • 2012-02-03
    • 2012-03-29
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 2017-01-24
    • 2013-08-24
    相关资源
    最近更新 更多