在i386 arch上编写bootloader汇编代码,无法正确输出到终端

时间:2017-03-03 00:02:50

标签: assembly x86

这是我第一次真正发帖提问。如果有一些我不遵守的格式/习俗,我很抱歉,如果是这样,请告诉我。

我在OS类的介绍中,我们应该编写一个bootloader。分配的一部分是使用INT 0x10中断向终端输出一个数字。例如,我想将某个寄存器中十六进制数0xFFF表示的字节数打印到其十进制等效值4095.首先,我编写汇编只是将存储值输出到其十进制等值:

.globl main
.code16

main:
    movw $0x9000, %ax
    movw %ax, %ss
    xorw %sp, %sp

    movw $0x0003, %ax
    int $0x10

    movw $0, %ax
    movw %ax, %ds
    movw %ax, %es

    mov $0xfff, %eax        # test value, decimal rep is 4095

    mov $0, %bl

    call div10

div10:

    mov $10, %ecx           # divisor
    mov $0, %edx            # set register to 0 - will store remainder
    div %ecx

    push %eax               # push result to stack
    mov %dl, %al            # move remainder value to %al for output
    add $0x30, %al          # add '0' to value to attain ascii equiv
    mov $0x0E, %ah
    int $0x10               # INT 0x10 instruction to print to terminal
    pop %eax                # pop test value back to eax reg

    cmp $0, %eax            # if eax is 0, conversion is complete
    je return

    call div10

return:

这段代码的输出是5904,考虑到我以相反的顺序输出,这是有道理的。我试着按正确的顺序输出数字到堆栈,然后用计数器弹出:

.globl main
.code16

main:
    movw $0x9000, %ax
    movw %ax, %ss
    xorw %sp, %sp

    movw $0x0003, %ax
    int $0x10

    movw $0, %ax
    movw %ax, %ds
    movw %ax, %es

    mov $0xfff, %eax # test value

    mov $0, %bl

    call div10

div10:

    mov $10, %ecx           # divisor
    mov $0, %edx            # set register to 0 - will store remainder
    div %ecx

    push %dx                # push digit onto stack
    add $1, %bl             # counter for number of digits - inc by 1

    cmp $0, %eax            # if eax is 0, conversion is complete
    je print_bytes

    call div10

print_bytes:

    sub $1, %bl      # counter decremented till 0
    mov $0, %ecx     # set registers to 0
    mov $0, %eax
    pop %cx          # pop digit value to %cx register
    mov %cl, %al     # move to %al to be output

    add $0x30, %al   # add '0' char to convert to ascii equivalent
    mov $0x0E, %ah
    int $0x10        # interrupt to print to screen

    cmp $0, %bl
    je return
    call print_bytes

return:

对于给定的测试值(0xFFF,转换为4095十进制),它输出'4ééé'。它似乎正确输出第一个数字,然后无法正确输出剩余的数字。我究竟做错了什么?我觉得在弹出我的价值观时会发生一些事情。

我现在才学习汇编(通常使用Java,C ++等高级语言),所以我确信编码实践有问题。请指出这些给我!我感谢任何/所有反馈。

编辑:修正了问题。 @Jester建议不使用call div10似乎解决了这个问题。我很感激帮助!

0 个答案:

没有答案