关于asmtutor.com中sprintLF函数未显式添加终止空字符的技术疑问
关于asmtutor.com中sprintLF函数未显式添加终止空字符的技术疑问
嘿,这个问题问到点子上了!咱们来把这个逻辑拆明白,你担心的segfault风险其实是不会发生的,原因藏在代码的细节里:
首先,咱们回头看这段代码里的关键步骤:
mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed push eax ; push the linefeed onto the stack so we can get the address
这里的eax是32位寄存器,所以当我们把0Ah(也就是十进制的10)mov进eax时,实际上eax里的值是0x0000000A——后面跟着三个空字节(0)。然后push eax是把整个32位寄存器的值压入栈,这就意味着栈上现在的布局是:栈顶第一个字节是换行符0Ah,紧接着的三个字节全是0。
而sprint里的strlen逻辑是从eax指向的地址开始,逐个字节找第一个0字符。当它读到0Ah之后,下一个字节就是0,立刻就会停止,返回的长度是1——刚好就是换行符的长度,完全符合我们的需求。
那为什么不会出现undefined行为或者segfault呢?
- 首先,我们访问的是进程自己的栈内存,这是合法可访问的区域,不会触发内存访问错误;
- 其次,
strlen根本不会有机会越界,因为它在换行符之后第一个字节就遇到了终止空字符,立刻停止扫描。
换句话说,这段代码其实间接通过32位寄存器的赋值和压栈操作,自动带上了终止空字符,只是没有写得那么直白而已。如果这里用的是push byte 0Ah(只压一个字节的换行符),那才需要手动在栈上补一个空字符,否则strlen才会一直往下扫,导致问题。
备注:内容来源于stack exchange,提问作者vmonteco
相关产品推荐
相关产品推荐

