Working on a simple hello.s for a class, got it working with int 0x10
/AH=0x0E
I would like to simplify the code with AH=0x13, which should print a string. But it doesn't work for reasons I don't understand. Code is as follows:
.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
Code is built/run with:
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
The print
routine prints "Hello World", the print_string
routine moves the cursor correctly but prints no characters.
I've verified with GDB that all segment registers are zero'd, and have tried variations where I zero them explicitly. No changes. Any ideas what I'm doing wrong here? I've verified in the Seabios source that this interrupt is supported.
The problem is the --nographic
option. Something about the nature of attribute-based output doesn't allow qemu to print strings that have attributes. But this isn't a complete answer, because the SeaBios source implies that there's effectively no difference between how these two interrupts print to the screen.