我试图在NASM中编写代码以获取给定字符串的长度.但是给出了一些垃圾值作为长度.代码如下:
section .data
a db "nitin",10,0
msg db "length = %d",10,0
section .text
global main
extern printf
main:
nop
xor eax,eax
mov eax, a
xor edx,edx
length:
mov dl, byte[eax]
cmp dl,0
je print
inc eax
jmp length
print:
pusha
push eax
push msg
call printf
add esp,8
popa
done:
nop
Run Code Online (Sandbox Code Playgroud)
结果如下所示:长度= 132445678
你能帮我解决一下我的错误吗?
谢谢
代码段中的EAX遵循字节的地址,而不是字符串中的索引.因此,不是长度,而是打印出终止空字符的地址.
重新设计EAX从零开始并读取地址[a + eax]处的字节,或者在打印出长度之前从EAX中减去a的地址.要么工作.
编辑:对于第一种方法,主循环看起来像这样:
main:
nop
xor eax,eax ; removed the mov eax,a line - eax stays zero
xor edx,edx
length:
mov dl, byte[a+eax] ; eax is the index in the string
cmp dl,0
;The rest stays the same
Run Code Online (Sandbox Code Playgroud)
对于第二种方法,循环保持不变,但打印部分获得额外的sub:
print:
sub eax, offset b ; convert from address to index
pusha
push eax
push msg
; The rest is the same
Run Code Online (Sandbox Code Playgroud)
然而,这将是最短的方式:
main:
nop
mov edi, a ; the string we're scanning
xor al, al ; That's what we're scanning the string for - a null valued byte
mov ecx, 0ffffffffh ; we bet on string being null terminated - no hard limit on string scanning
repne scasb ; Once this finishes, ECX is (0xffffffff - length - 1) (because the terminating null is counted too)
mov eax, 0fffffffeh
sub eax, ecx ; Now eax is (0xffffffff - 1 - ecx), which is string length
print:
; Same as before
Run Code Online (Sandbox Code Playgroud)
查找scas命令以及如何将其与repxx前缀一起使用.这几乎就像在英特尔CPU指令集中实现了一部分C RTL(strlen,strcpy等).
在旁注中,该片段有两条完全无关的行 - xor eax, eax并且xor edx, edx在函数的开头.两者都将一个寄存器归零,无论如何都会在下一行中被覆盖.