为什么 strlen 的 REPNE SCASB 实现可以工作?

2023-12-04

为什么这段代码有效?

http://www.int80h.org/strlen/表示字符串地址必须位于EDI为.....注册scasb工作,但这个汇编功能似乎并没有做到这一点。

汇编代码为mystrlen:

global  mystrlen
mystrlen:
        sub             ecx, ecx
        not             ecx
        sub             al, al
        cld
        repne scasb
        neg             ecx
        dec             ecx
        dec             ecx
        mov             eax, ecx
        ret

C main:

int mystrlen(const char *);
int main()
{
    return (mystrlen("1234"));
}

汇编:

nasm -f elf64 test.asm
gcc -c main.c
gcc main.o test.o

Output:

./a.out
echo $?
4

问题中的代码是 strlen 的 32 位版本,它仅部分地在 64b 环境中工作,有点“偶然”(因为大多数软件实际上都在现实中工作,无论如何;))。

64b 环境的一个意外影响是(在 64b linux 操作系统使用的 System V ABI 中,其他 64b 平台可能遵循不同的调用约定,从而使此无效!),函数调用中的第一个参数通过rdi注册,并且scasb正在使用es:rdi在 64b 模式下,所以这自然适合在一起(正如小丑的回答所说)。

其余64b环境效果不太好,该代码将返回4+G长字符串的错误值(我知道,在实际使用中极不可能发生,但可以通过提供这么长字符串的综合测试来尝试)。

修复了 64b 版本(例程结束时还利用 rax=0 来执行这两项操作neg ecx and mov eax,ecx在单个指令中):

global  mystrlen
mystrlen:
        xor       ecx,ecx    ; rcx = 0
        dec       rcx        ; rcx = -1 (0xFFFFFFFFFFFFFFFF)
        ; rcx = maximum length to scan
        xor       eax,eax    ; rax = 0 (al = 0 value to scan for)
        repne scasb          ; scan the memory for AL
        sub       rax,rcx    ; rax = 0 - rcx_leftover = scanned bytes + 1
        sub       rax,2      ; fix that into "string length" (-1 for '\0')
        ret
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 strlen 的 REPNE SCASB 实现可以工作? 的相关文章

随机推荐

  • Capistrano 和 X-Sendfile

    我正在尝试让 X Sendfile 使用 capistrano 来处理我的繁重附件 我发现 X Sendfile 不适用于符号链接 我如何处理 Capistrano 符号链接的文件夹内的文件 我的网络服务器是apache2 passenge
  • 具有可选值的 Scala 案例类副本

    我想制作一个案例类的副本 并使用第二个案例类中的可选值对其进行更新 case class A id Int a String b String c String case class Update a Option String b Opt
  • 如何在WP8中使用AudioVideoCptureDevice录制视频

    Here它说我可以使用录制视频AudioVideoCaptureDevice但没有提供示例或帮助 我需要做以下事情 将视频录制到流中DONE 显示录制视频的缩略图 可以是视频录制时捕获的帧 DONE 回放录制的视频DONE 更改相机的分辨率
  • 通过gradle上传到artifactory时如何更改jar文件名

    我正在使用 gradle 来将 jar 上传到神器 我设法做到了 但是我试图更改 jar 文件名 但它并没有真正让我这么做 我使用的是shadowJar来打包 我就是这样做的 apply plugin java apply plugin m
  • 在 matlab 中搜索结构的平行行以查找常见项目

    我存储了 行 列 值 信息 key1 1 1 1 2 1 3 4 2 3 4 attribute1 2 3 4 2 5 如下 Structure A1 key row1 1 1 1 4 3 key col1 1 2 3 2 4 attrib
  • 如何在 Struts 2 中使用 标签?

    我有下面的 Struts 2 标签 我需要检查属性是否value attr row Commentaire不为空 如果不为空 则显示一个小图标 用户可以单击它并查阅属性的内容value attr row Commentaire 我怎样才能使
  • 允许多个 IP 通过 .htaccess 访问 WordPress 站点管理

    我目前有一个正在升级的 WordPress 网站 并且在 htaccess 文件中有一个维护重定向设置 我可以允许我自己的 IP 访问站点和管理员 但如何允许其他编辑者也可以访问多个 IP 访问 我目前正在使用 RewriteEngine
  • java GC 是怎么回事? PermGen 空间已满?

    我不知道我的 java 进程发生了什么 这个过程就是一个索引过程 它从一组 zip 文件中读取文档 并将它们添加到 lucene 索引中 GC日志显示只是连续运行Full GC 4959 569 Full GC 19960K gt 1996
  • 如何让进度条在浏览器导航时正常工作?

    我正在 C 上使用进度条和 Web 浏览器控件 但我不知道如何在导航时制作一个平滑的进度条 您是否能一步一步创建它 我将不胜感激 Use WebBrowser ProgressChanged Event private void WebBr
  • 从 JavaMail 消息中预取预览文本

    我正在使用 JavaMail 1 5 2 读取来自 IMAP 帐户的邮件 为了减少对主机的请求数量 我预取了一些消息数据 例如发件人 日期 消息 ID 等 Folder folder store getFolder inbox folder
  • 为什么有这么多方法来比较平等?

    如果我想比较两个值是否相等 有多种选择 例如 eq对于符号 对于数字 char equal对于角色 string equal对于字符串 eql用于符号 数字和字符串 equal对于除符号之外的所有内容 我希望到目前为止我做对了 现在 作为
  • IntelliSense 不适用于 MVC Razor cshtml 页面

    我遇到了 没有为扩展 cshtml 注册构建提供程序 我的一个使用 MVC 3 的项目出现错误 这使得自动完成功能不起作用 程序仍然运行 但是很烦人 我已经准备好 Web config 并包含所有必需的引用 事实上 我的其他具有相同配置的项
  • 如何从 NSArray 中删除具有相同值的重复对象

    我有一个NSDictinary看起来像这样 NSArray duplicates name a id 123 name c id 234 name a id 431 name c id 983 name a 038 如何删除同名的词典 例如
  • java.util.Arrays 不工作 java 8

    我最近更新为在计算机上使用 Java 8 进行 Eclipse 我之前一直在使用 Java 7 起初 更新似乎工作正常 因为我可以编译并运行一个简单的hello world 程序 然而 当我开始导入我之前正在处理的使用该类的项目时java
  • 声纳分析失败并出现 SocketTimeoutException

    当尝试从 ant 运行 Sonar 时 由于 SocketTimeoutException 我遇到了偶发故障 设置 我在 RHEL 6 机器上运行 Sonar 4 0 配置为与 Postgres 9 2 一起运行 我使用 Jenkins 1
  • 如何使用带有 POST 参数的 JSF 隐式重定向

    在我的 JSF 应用程序中 我有两个页面 list jsf and details jsf 每个页面都有自己的控制器和视图范围 在list jsf我有一个
  • 如何在 mutate 语句中对两列进行排序和粘贴?

    我希望对两列进行排序并将其粘贴到新列中 test data frame a jump b jam test gt mutate new paste sort a b 预期输出是包含三列的数据框 a jump b jam c jamjump
  • 嵌入式模式下的 JSP 单元测试

    我正在构建一个小型框架来对 JSP 进行单元测试 这些 JSP 有一些自定义标签 除此之外它们并没有什么特别的 尽管有许多可用的 Java 单元测试解决方案 但我不喜欢使用启动单独的成熟 JSP 容器 部署应用程序并通过 TCP 连接收集结
  • 如何使用 selenium python 向下滚动谷歌工作页面

    我正在尝试使用以下行向下滚动职位发布 但有时会给出正确的结果 向下滚动到末尾 有时则不会 html driver find element by tag name html time sleep 5 html send keys Keys
  • 为什么 strlen 的 REPNE SCASB 实现可以工作?

    为什么这段代码有效 http www int80h org strlen 表示字符串地址必须位于EDI为 注册scasb工作 但这个汇编功能似乎并没有做到这一点 汇编代码为mystrlen global mystrlen mystrlen