【问题标题】:Trouble finding the length in the string无法找到字符串中的长度
【发布时间】:2013-09-12 13:49:16
【问题描述】:

我在这里找到了代码,在 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次。当它打印时,它不会打印实际的字符串,而是一些随机字母。有谁知道为什么它不起作用?我正在尝试在引导扇区中运行它,所以我真的没有任何调试工具。

【问题讨论】:

  • 您的程序偏移设置是否正确?
  • 我已声明代码从[org 0x7c00] 开始,这是我设置的唯一其他内容。我还没有设置基指针和堆栈指针,因为我并没有真正在这些打印字符串中使用它们。这会影响它吗?
  • 这是完整的源代码吗?怎么说执行将从第一条mov 指令开始,而不是HELLO_MSG 字符串(即执行垃圾)?此外,用于清除方向标志的指令是cld,而不是cdqcdq 用于在除法之前将eax 符号扩展为edx)。

标签: assembly x86 nasm bios


【解决方案1】:

你的代码还有更多问题:

  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 在运行引导加载程序之前为堆栈“分配”小空间,因此它不会影响任何东西。

  4. 这一行

     mov al, byte bl
    

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

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

【讨论】:

  • 1.是的,我在实际代码中这样做,但这里只是打印的 sn-p。 2. 我不知道我是怎么想出 cdq 的……抱歉。 3. 我完全没有想到。谢谢你让我知道。 4.这个解决了!我感谢您的帮助!谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-12-28
  • 2018-01-03
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多