1

你能帮我理解下面两个组装说明的目的吗?(有关更多上下文,最后是汇编 + C 代码)。谢谢 !

movzx  edx,BYTE PTR [edx+0xa]
mov    BYTE PTR [eax+0xa],dl

====================================

汇编代码如下:

push   ebp    
mov    ebp,esp
and    esp,0xfffffff0
sub    esp,0x70
mov    eax,gs:0x14
mov    DWORD PTR [esp+0x6c],eax
xor    eax,eax
mov    edx,0x8048520
lea    eax,[esp+0x8]
mov    ecx,DWORD PTR [edx]
mov    DWORD PTR [eax],ecx
mov    ecx,DWORD PTR [edx+0x4]
mov    DWORD PTR [eax+0x4],ecx
movzx  ecx,WORD PTR [edx+0x8]
mov    WORD PTR [eax+0x8],cx
movzx  edx,BYTE PTR [edx+0xa]    ; instruction 1
mov    BYTE PTR [eax+0xa],dl     ; instruction 2
mov    edx,DWORD PTR [esp+0x6c]
xor    edx,DWORD PTR gs:0x14
je     804844d <main+0x49>
call   8048320 <__stack_chk_fail@plt>
leave  
ret

====================================

下面的 C 源代码(不包含库):

int main() {
    char str_a[100];    
    strcpy(str_a, "eeeeefffff");
}
4

1 回答 1

5

它内联了 strcpy() 调用,代码生成器可以判断需要复制 11 个字节。字符串文字“eeeeefffff”有 10 个字符,零终止符有一个额外的字符。

代码优化器将复制循环展开为 4 个移动,移动 4 + 4 + 2 + 1 个字节。之所以需要这样做,是因为没有移动 3 个字节的处理器指令。您询问的有关复制第 11 个字节的说明。使用 movzx 有点矫枉过正,但它可能比加载 DL 寄存器更快。

更改字符串时观察生成的代码中的更改。添加一个额外的字母应该展开到 3 个移动,4 + 4 + 4。当字符串变得太长时,你应该看到它回退到 memmove 之类的东西。

于 2013-08-18T17:46:18.690 回答