Reputation: 176
I found the code here, on Stack Overflow to get the length of the string. Here's the code:
HELLO_MSG: db 'Hello, world!', 0
mov ebx, HELLO_MSG
call print_string
print_string:
call str_len
mov ecx, eax ; puts the length of the called string into ecx register
cdq ; clear the direction flag; not sure if this is needed
mov ah, 0x0e ; scrolling teleype BIOS routine
printing:
mov al, byte bl
int 0x10
inc ebx
loop printing
ret
str_len:
mov eax,ebx
l00p:
cmp byte[eax], 0
jz lpend
inc eax
jmp l00p
lpend:
sub eax, ebx ; puts the length of the string into eax register
ret
The problem is that when function calls str_len
, it loops only 3 times, sometimes it does 2 times. And when it prints, it doesn't print the actual string, but some random letters. Does anybody know why it doesn't work? I'm trying to run it in the boot sector, so I don't really have any debugging tools.
Upvotes: 0
Views: 109
Reputation: 6403
There are more problems in your code:
You should jump over string constant on the beginning
mov ebx, HELLO_MSG
call print_string
jmp $
HELLO_MSG: db 'Hello, world!', 0
print_string:
...
cdq
instruction is not for clearing DF
. cdq
is used to convert doubleword in eax
into sign-extended edx:eax
value. You should cld
instead. But you're right, when you don't use any string instructions (cmpsb
, movsb
...), DF
usually isn't important. I haven't setup base and stack pointers yet, because I'm not really using them within these printing strings.
Yes, but you use call
instruction, which pushes return address on stack. Usually, BIOS "allocates" small space for stack before running bootloader, so it shouldn't affect anything.
This line
mov al, byte bl
will set AL
equal to BL
, which is not the thing you want. You should use indirect byte addressing with ebx
.
mov al, byte [ebx]
int 0x10
inc ebx
...
Upvotes: 2