string - 汇编中字符串的长度(对程序如何工作的困惑)
问题描述
我有一个汇编程序,它在 ax 寄存器中写入字符串的长度,但我对一些指令有点困惑。
include \masm32\include64\masm64rt.inc
.data
string db "mama", 0 ; so here I declared a string "mama". What happens in memory?
.code
main proc
xor ax, ax ; here I initialize ax with 0.
lea rsi, string ; here, I move in rsi register the adress of string, right? But how the string is stored in memory? Now in rsi I have the adress of the first char "m" of "mama" string?
@@: ; this sign creates an anonymous label
cmp byte ptr [rsi], 0 ; so this says compare 0 with with 1 byte found at the adress pointed to by rsi, right? But I still don't get it. Why 1 byte? rsi is pointing to the first char or to the whole string?
jz @F ; jump if zero to the nearest @@ (forward)
inc ax ; so now i'm pointing to the first character so ax=1
inc rsi ; here what happen? The pointer is incremented to point to the second char from string?
jmp @B ; jump to the nearest @@ (backward)
@@:
invoke ExitProcess, 0 ; invoke ExitProcess API
ret
main endp
end
我的困惑是我不确定我是否考虑过这个程序是如何以正确的方式工作的。我这样想对吗?
解决方案
string db "mama", 0
4 个字节0x6d 0x61 0x6d 0x61
('mama')存储在程序内存的数据段中的某处。string
将第一个字节的地址存储在数据段中,即“m”。
xor ax, ax
lea rsi, string
相信手术应该是lea rsi, [string]
。(编辑:正如Peter Cordes在下面的评论中提到的,在 MASM 汇编器中,这种语法很好)
string
指向第一个字符的地址。现在rsi
指向同一个地址。
@@: ; this sign creates an anonymous label
cmp byte ptr [rsi], 0
rsi 指向整个字符串的开头。比较操作将 rsi 处的一个字节与零进行比较。如果为零,则假定字符串结束并跳转到退出:
jz @F ; jump if zero to the nearest @@ (forward)
如果 rsi 的值不为零:
inc ax
请记住,我们将字符串的长度存储在 ax 中。因此,对于每个有效字符,我们递增ax
1。
inc rsi
jmp @B ; jump to the nearest @@ (backward)
指向rsi
下一个字符 ('a') 并跳转到 @@。第一个 @@ 之后的代码将再次检查下一个字符 ('a') 是否为零,并将计数 ( ax
) 增加 1,因此ax
将变为 2。这将一直持续到达到 0,程序假定结束的字符串。
@@:
invoke ExitProcess, 0 ; invoke ExitProcess API
ret
main endp
end
退出代码。
旁注:您可以使用像 gdb 这样的程序,在开始时带有断点来遍历每个步骤。使用info registers
命令,您可以检查它们的值。向谷歌询问更高级的命令/方法。
推荐阅读
- javascript - 谷歌地图不适用于 HTTP
- doctrine-orm - Symfony 巨大的日期时间对象,在时区有数百个转换
- c - 在没有 Internet 访问的情况下将头文件安装到 linux 机器上
- java - 如何简化填写始终具有相同内容的表单?
- angular - email.invalid 在 angularmaterial 中不起作用
- ssl - curl证书验证失败
- unity3d - OnTriggerExit 持续时间比正常时间长?
- fork - 请有人解释一下,B行中循环的目的(及其wait())是什么?
- jquery - 当滚动条在模态中到达底部时,启用的按钮不起作用
- hyperledger - Hyperledger Composer 更新参与者详细信息