C-内存分配优化:从堆到堆栈



我正在对32-bit x86体系结构上的二进制文件进行一些反向工程任务。

最近,我发现了C源代码到汇编程序的一些有趣的优化。

例如,原始源代码就像(此源代码来自openssl library):

powerbufFree = (unsigned char *)malloc(powerbufLen);

和汇编(gcc version 4.8.4 -O3)之后,汇编代码如下:

807eaa0: cmp eax, 0xbff                         # eax holds the length of the buf.
807eaa5: mov dword ptr [ebp-0x68], eax          # store the length of powerbuf on the stack
807eaa8: jnle 0x807ec60                         # 0x807ec60 refers to the malloc
807eaae: mov edx, eax
807eab0: add eax, 0x5e
807eab3: and eax, 0xfffffff0
807eab6: sub esp, eax
807eab8: lea eax, ptr [esp+0x23]
807eabc: and eax, 0xffffffc0
807eabf: add eax, 0x40
807ead3: mov dword ptr [ebp-0x60], eax  # store the base addr of the buf on the stack.

令我惊讶的是,BUF确实是在堆栈上分配的!! 这似乎是对我的堆分配的优化,但我不确定。

所以这是我的问题,上述优化(malloc->堆栈分配)是否对任何人来说都是熟悉的?是否有意义?谁能提供有关此类优化的手册/规范?

来自bn_exp.c的来源:

0634 #ifdef alloca
0635     if (powerbufLen < 3072)
0636         powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
0637     else
0638 #endif
0639     if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
0640         goto err;

请注意,0xbff等于3071。在支持它的系统上,alloca确实堆栈分配。Linux使用的GNU版本是正确的,而BSD实现从AT&amp; t(根据FreeBSD)复制了32V UNIX的API。

您仅查看第639号线。但是,如果定义了alloca,则C代码匹配您的汇编。

如果分配相对较小,优化本身通常用于避免使用malloc作为临时缓冲区的费用。对于1999年,可以使用VLA(因为C.2011,VLA是可选的功能)。

有时,优化仅使用固定尺寸的缓冲区,这些缓冲区具有合理的小尺寸。例如:

char tmp_buf[1024];
char *tmp = tmp_buf;
if (bytes_needed > 1024) {
    tmp = malloc(bytes_needed);
}
/* ... */
if (tmp != tmp_buf) {
    free(tmp);
}

相关内容

  • 没有找到相关文章

最新更新