x86 - 尝试在 x86 GAS 中实现 strlen
问题描述
所以我对汇编编程非常陌生(非常新),并且正在尝试编写一个可以计算字符串长度的函数。
我觉得我在清除寄存器中的值或指针的增量时遇到了一些问题,因为返回的值对我来说始终是“4571 + 长度”。
基本上,如果我的字符串长度为 0,我会得到 4571 作为返回值。如果我的字符串长度为 6,我会得到 4577 作为返回值,等等。
这是我的代码,任何帮助将不胜感激:
.globl my_strlen
my_strlen:
pushq %rbp
movq %rsp, %rbp
pushq %r12
pushq %r13
movq $0, %rax
cmp $0, (%rdi)
jne my_strlen_loop
ret
my_strlen_loop:
inc %rax
inc %rdi
cmp $0, (%rdi)
jne my_strlen_loop
popq %r13
popq %r12
popq %rbp
ret
解决方案
这段代码有两个问题。
首先,cmp
指令没有指定大小,并且操作数都不是寄存器,所以它是模棱两可的。对于大多数指令(如mov $0, (%rdi)
),GAS 会拒绝组装它,但cmp
由于某种原因组装到cmpl
,比较一个 dword。将助记符更改为cmpb
显式。
其次,在第一次 ret 之前,它不会弹出被推送的寄存器。最好跳到最后(并有一个 ret)。
推荐阅读
- mongodb - 如何将 MongoDB Shell 与外部副本集连接
- node.js - 如何从 S3 读取 CSV 流,但从文件中间的某个位置开始?
- c# - 如何获得每个 item2 & item3 组合的最大日期时间?
- node.js - 在 Node.js 中写入关于发布请求的数据
- google-bigquery - 如何提高 BigQuery 的频繁读取?
- vb.net - 使用 VB.NET 在网格中动态创建复选框时,不会出现在 UI 上
- regex - 如何在 grep -P '(?!.*//)word' 中转义 / char 以转义评论
- java - 如果年龄低于 50,则更改行颜色
- apache-camel - 两个独立代理上的 Artemis 客户端负载平衡
- python - 如何在单行中输入不同的数据类型?