我有一个函数string_length,它具有以下汇编代码
0x08048e90 <+0>: push %ebp
0x08048e91 <+1>: mov %esp,%ebp
0x08048e93 <+3>: mov 0x8(%ebp),%edx // assign whatever I declared into edx
0x08048e96 <+6>: mov $0x0,%eax // assign eax = 0
0x08048e9b <+11>: cmpb $0x0,(%edx) // compare edx to byte of 0 (null..?)
0x08048e9e <+14>: je 0x8048ea9 <string_length+25> // if equal, jump to +25
0x08048ea0 <+16>: add $0x1,%eax // else, add 1 to eax
0x08048ea3 <+19>: cmpb $0x0,(%edx,%eax,1) // compare byte 1*eax+edx with 0,
0x08048ea7 <+23>: jne 0x8048ea0 <string_length+16> // if not equal, back to +16
0x08048ea9 <+25>: pop %ebp // pop ebp
0x08048eaa <+26>: ret
由于函数名是string_length,我假设它将返回字符串中的字符数。
我感到困惑的是
cmpb $0x0,(%edx)
这是将edx指向的字节与0的字节进行比较,而ASCII中的0是否为空。?
和
cmpb $0x0,(%edx,%eax,1)
以字节为单位比较1 * eax + edx。如果edx是一个字符串,那是否意味着将首先将edx转换为其ascii值,然后执行计算?
答案 0 :(得分:4)
此:
cmpb $0x0,(%edx)
取一个EDX指向的字节(即包含地址)并将其与零进行比较。这样:
cmpb $0x0,(%edx,%eax,1)
取一个EDX + EAX指向的字节并将其与零进行比较。 EDX充当字符串基指针,EAX是索引。比例是1,因为我们正在使用字节。以这种方式思考整个循环:for(eax=0; edx[eax] != 0; eax++)
。
答案 1 :(得分:1)
等效的C代码是这样的:
int string_length(const char *edx)
{
int eax = 0;
while (edx[eax] != NULL) eax++;
return eax;
}