【发布时间】:2021-05-09 13:01:52
【问题描述】:
我是 asm 新手,很困惑...
这是我在nasm 程序集中工作的strlen 函数的循环:
.loop: inc rax
inc rbx
cmp [rbx], byte 0
jne .loop
ret
但是我在教程中看到过 cmp bl, 0 这样的东西,但是当我尝试时,我得到了错误的长度。
我尝试过cmp [bl],0,但在组装时出现invalid effective address 错误。
我也试过cmp rbx, 0。但是程序永远不会停止所以我最好的猜测是我
将一个非常大的地址与永远不会发生的 0 进行比较。
如何理解这种行为?为什么我不能使用cmp rbx, 0 但有些
人们可以使用cmp bl, 0 吗?
如果您找到更具描述性的标题,请随时编辑标题。
【问题讨论】:
-
您能否展示您创建的完整
strlen过程,以及您看到的使用cmp bl, 0的示例? -
如果将字符加载到寄存器中,则可以将其与 0 进行比较。如果不是,则需要
cmp的内存操作数。顺便说一句,cmp rbx,0将指针与 NULL 进行比较是正确的;在将指针环绕到 0 之前,您会点击一个未映射的页面。 -
你明白
cmp byte [rbx], 0是什么意思吗?应该有很多教程来解释寻址模式和内存与寄存器,例如找到链接自stackoverflow.com/tags/x86/info 的教程或指南并阅读。这也应该清楚为什么cmp [bl], 0甚至不能汇编(x86 不允许 8 位地址),以及为什么即使它可以运行它也不会做你想做的事情。 -
还有另一种搜索 NUL 终止符的方法:REPNE SCAS。
-
你不用
inc rax,把字符串的开头移到rax中,然后减去你刚刚找到的0-Byte的地址,就可以得到长度了。