【发布时间】:2021-11-21 20:13:02
【问题描述】:
为一个类编写一个简单的 hello.s,让它与 int 0x10/AH=0x0E 一起使用
我想用 AH=0x13 简化代码,它应该打印一个字符串。但由于我不明白的原因,它不起作用。代码如下:
.code16
.global start
start:
mov $start, %sp # Put the stack beneath us
call setup # Setup BIOS modes
xor %ax, %ax
mov %ax, %es # This is already zero, but let's make that clear
mov $hello, %bp
mov $hello_len, %cx
call print # Prints Hello World
mov $hello, %bp
mov $hello_len, %cx
call print_string
call done # Halt
setup:
mov $0x00, %ah # Set Video mode to:
mov $0x03, %al # 80x25 Color Text Mode
int $0x10 # Do it
ret
print: # This routine works
mov %bp, %si
add %bp, %cx
loop: cmp %si, %cx
jz print_end
lodsb # Load and increment source index
mov $0x0E, %ah # Print single character
int $0x10 # Do it
jmp loop
print_end: ret
print_string: # This routine does not work
mov $0x0100, %dx # DH: Row, DL: Column
mov $0x1301, %ax # AH: Write String, AL: Update Cursor
mov $0x0007, %bx # BH: Page Number, BL: Color (Light Gray)
int $0x10 # Do it
ret
done:
hlt
hello:
.ascii "Hello World"
hello_len = . - hello
.= 0x01FE
.byte 0x55, 0xAA
代码是通过以下方式构建/运行的:
as hello.s -o hello.o
ld -N -e start -Ttext=0x7c00 hello.o -o hello.elf
objcopy -O binary hello.elf hello
qemu-system-i386 -hda hello --nographic
print 例程打印“Hello World”,print_string 例程正确移动光标但不打印任何字符。
我已经用 GDB 验证了所有段寄存器都归零,并尝试了我明确归零的变体。没有变化。有什么想法我在这里做错了吗?我已在 Seabios 源代码中验证支持此中断。
【问题讨论】:
-
似乎您不能在同一个调用中同时打印和更新光标位置。为了澄清,请尝试使用 al=0。
-
@500-InternalServerError,事先添加一个 AH=0x03 调用以获取确切的光标位置,然后使用该光标位置打印,会导致相同的行为。 (除了在同一行而不是在新行上,因为我在原始代码中对行进行了硬编码)。
-
您似乎没有在任何地方设置
%es。函数13h需要%es:%bp指向字符串。 -
@sj95126 在我原来的问题中讨论过,验证为零,但我可以添加一个明确的归零来明确这一点
-
代码对我有用 - 我得到两个“Hello World”,第一个是普通白色,第二个是粗体白色。
标签: assembly x86 system-calls interrupt bios