无法在字符串中查找长度

时间:2013-09-12 13:49:17

标签: assembly x86 nasm bios

我在Stack Overflow上找到了代码来获取字符串的长度。这是代码:

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

问题是当函数调用str_len时,它只循环3次,有时会循环2次。当它打印时,它不会打印实际的字符串,而是一些随机字母。有谁知道为什么它不起作用?我正试图在引导扇区中运行它,所以我没有任何调试工具。

1 个答案:

答案 0 :(得分:2)

您的代码中存在更多问题:

  1. 你应该在开头跳过字符串常量

    mov ebx, HELLO_MSG
    call print_string
    jmp $
    
    HELLO_MSG: db 'Hello, world!', 0
    
    print_string:
    ...
    
  2. cdq指示不用于清除DFcdq用于将eax中的双字转换为符号扩展edx:eax值。你应该cld。但是你是对的,当你不使用任何字符串指令(cmpsbmovsb ...)时,DF通常并不重要。
  3.   

    我还没有设置基本和堆栈指针,因为我并没有真正在这些打印字符串中使用它们。

    是的,但你使用call指令,它会在堆栈上推送返回地址。通常,BIOS在运行bootloader之前为堆栈“分配”小空间,因此它不会影响任何内容。

  4. 这一行

     mov al, byte bl
    

    会将AL设置为等于BL,这不是您想要的。您应该使用ebx的间接字节寻址。

    mov al, byte [ebx]
    int 0x10
    inc ebx
    ...