I have a piece of code that calls a BIOS text output function, INT 0x10, AH=0x13:
static void __stdcall print_raw(uint8_t row, uint8_t col, uint8_t attr,
uint16_t length, char const *text)
{
__asm__ __volatile__ (
"xchgw %%bp,%%si\n\t"
"int $0x10\n\t"
"xchgw %%bp,%%si\n\t"
:
: "d" (row | (col << 8)), "c" (length), "b" (attr), "a" (0x13 << 8), "S" (text)
);
}
I have another function which can print a number on the screen:
void print_int(uint32_t n)
{
char buf[12];
char *p;
p = buf + 12;
do {
*(--p) = '0' + (n % 10);
n /= 10;
} while (p > buf && n != 0);
print_raw(1, 0, 0x0F, (buf + 12) - p, p);
}
I spent significant time trying to figure out why nothing was coming up on the screen. I dug into it and looked at the code generated for print_int:
.globl print_int
.type print_int, @function
print_int:
.LFB7:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl $10, %ecx
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %esi
pushl %ebx
.cfi_offset 6, -12
.cfi_offset 3, -16
leal -8(%ebp), %esi
leal -20(%ebp), %ebx
subl $16, %esp
movl 8(%ebp), %eax
.L4:
xorl %edx, %edx
decl %esi
divl %ecx
testl %eax, %eax
je .L6
cmpl %ebx, %esi
ja .L4
.L6:
leal -8(%ebp), %ecx
movl $4864, %eax
movb $15, %bl
movl $1, %edx
subl %esi, %ecx
#APP
# 201 "bootsect.c" 1
xchgw %bp,%si
int $0x10
xchgw %bp,%si
# 0 "" 2
#NO_APP
addl $16, %esp
popl %ebx
.cfi_restore 3
popl %esi
.cfi_restore 6
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
If you look closely at the loop at L4, you'll see that it never stores anything into buf. It has omitted the instruction! it just divides it down and never stores any characters into the buffer.