为什么用REPNE SCASB实施strlen工作?

编程入门 行业动态 更新时间:2024-10-25 10:24:36
本文介绍了为什么用REPNE SCASB实施strlen工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

为什么此代码有效?

www.int80h/strlen/表示字符串地址具有进入EDI寄存器以使scasb正常工作,但是此汇编函数似乎没有执行此操作.

www.int80h/strlen/ says that the string address has to be in EDI register for scasb to work, but this assembly function doesn't seem to do this.

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主程序:

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

编译:

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

输出:

./a.out echo $? 4

推荐答案

问题中的代码是32位版本的strlen,仅在64b环境中部分运行,有点偶然"(因为大多数SW都可以运行)实际上,无论如何;)).

The code from the question is 32 bit version of strlen, which works in 64b environment only partially, sort of "by accident" (as most of the SW works in reality, anyway ;) ).

64b环境的意外影响之一是(在64b linux操作系统使用的System V ABI中,其他64b平台可能遵循不同的调用约定,从而使此方法无效!),函数调用中的第一个参数被传递了rdi寄存器,并且scasb在64b模式下使用es:rdi,因此这很自然地适合在一起(正如Jester的回答所说).

One of the accidental effects of 64b environment is (in System V ABI, which is used by 64b linux OS, other 64b platforms may follow different calling convention, invalidating this!), that the first argument in function call is passed through rdi register, and the scasb is using es:rdi in 64b mode, so this naturally fits together (as the Jester's answer says).

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

Rest of the 64b environment effects are less good, that code will return wrong value for 4+G long string (I know, highly unlikely to happen in practical usage, but can be tried by synthetic test providing such long string).

修复了64b版本(例程的结尾也利用rax = 0在单个指令中同时执行了neg ecx和mov eax,ecx):

Fixed 64b version (also the end of routine exploits rax=0 to do both neg ecx and mov eax,ecx in single instruction):

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

更多推荐

为什么用REPNE SCASB实施strlen工作?

本文发布于:2023-07-30 00:42:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1245028.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:什么用   工作   SCASB   REPNE   strlen

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!