Assembly 找不到字符串的长度
我在这里找到了在堆栈溢出上获取字符串长度的代码。代码如下:Assembly 找不到字符串的长度,assembly,x86,nasm,bios,Assembly,X86,Nasm,Bios,我在这里找到了在堆栈溢出上获取字符串长度的代码。代码如下: 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
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次。当它打印时,它不会打印实际的字符串,而是一些随机字母。有人知道它为什么不起作用吗?我试图在引导扇区中运行它,因此我没有任何调试工具。您的代码中还有更多问题:
mov ebx, HELLO_MSG
call print_string
jmp $
HELLO_MSG: db 'Hello, world!', 0
print_string:
...
cdq
指令不用于清除DF
cdq
用于将eax
中的双字转换为符号扩展edx:eax
值。您应该改为cld
。但是你是对的,当你不使用任何字符串指令(cmpsb
,movsb
…)时,DF
通常并不重要李>
call
指令,它将返回地址推送到堆栈上。通常,BIOS在运行引导加载程序之前为堆栈“分配”小空间,所以它不会影响任何事情 mov al, byte bl
将AL
设置为BL
,这不是您想要的。您应该将间接字节寻址与ebx一起使用
mov al, byte [ebx]
int 0x10
inc ebx
...
您的程序偏移设置正确吗?我已声明代码从
[org 0x7c00]
开始,这是我设置的唯一其他内容。我还没有设置基指针和堆栈指针,因为我没有在这些打印字符串中真正使用它们。这会影响它吗?这是完整的源代码吗?怎么说执行将从第一条mov
指令开始,而不是在HELLO\u MSG
字符串中开始(即执行垃圾)?此外,用于清除方向标志的指令是cld
,而不是cdq
(cdq
用于在除法之前将eax
标志扩展到edx
)。是的,我在实际代码中这样做,但这里只是打印的一个片段。2.我不知道我是怎么想到干熄焦的。。。很抱歉。3.我完全没有想到这一点。谢谢你让我知道。4.这个修好了!我感谢你的帮助!非常感谢。