我在汇编中做了自己的strlen实现,但是它没有返回正确的值。 它返回string长度+4。 我不明白为什么..我希望你们中的任何一个做…
大会来源:
section .text [GLOBAL stringlen:] ; C function stringlen: push ebp mov ebp,esp ; setup the stack frame mov ecx,[ebp+8] xor eax,eax ; loop counter startLoop: xor edx,edx mov edx,[ecx+eax] inc eax cmp edx,0x0 ; null byte jne startLoop end: pop ebp ret
而主要的例程:
#include <stdio.h> extern int stringlen(char *); int main(void) { printf("%d",stringlen("h")); return 0; }
谢谢
大会 – 如何修改堆栈大小?
堆利用失败:内存损坏
如何从自身内部获取指向程序特定部分的指针? (也许与自我)
memcpy在linux中移动128位
x86 – 获取方向标志(DF)的当前状态
如何比较string中的字符与NASM x86_64 Linux程序集中的另一个字符
子指令如何导致无效指针读取?
当控制权返回时,操作系统是否会假定被调用者保存的寄存器?
Main()被调用之前Windows做了什么?
您不是访问字节(字符),而是双字。 所以你的代码是不是在寻找一个单一的终止零,它正在寻找4个连续的零。 请注意,并不总是返回正确的值+4,这取决于你的字符串包含的内存。
要解决这个问题,你应该使用字节访问,例如把edx dl 。
不知道这四个,但似乎很明显,它总是会返回适当的长度+ 1,因为即使从字符串读取的第一个字节为零, eax 总是增加。
section .text [GLOBAL stringlen:] stringlen: push ebp mov ebp,esp mov edx,[ebp+8] ; the string xor eax,eax ; loop counter jmp if then: inc eax if: mov cl,[edx+eax] cmp cl,0x0 jne then end: pop ebp ret
改变线
mov edx,[ecx+eax]
至
mov dl,byte [ecx+eax]
和
cmp edx,0x0 ; null byte
至
cmp dl,0x0 ; null byte
因为你一次只能比较字节。 以下是代码。 你原来的代码出错了。 对于“h”它将返回两个h +空字符。
section .text [GLOBAL stringlen:] ; C function stringlen: push ebp mov ebp,eax ; loop counter startLoop: xor dx,dx mov dl,byte [ecx+eax] inc eax cmp dl,0x0 ; null byte jne startLoop end: pop ebp ret
这里更简单的方法(仅限ASCII零终止字符串):
REPE SCAS m8
http://pdos.csail.mit.edu/6.828/2006/readings/i386/REP.htm
我认为你的公司应该在Jne之后。 我不熟悉这个集会,所以我不知道。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。