我有一个简单的C程序。比方说,我有一个长度为20的int和一个char数组。我需要总共24个字节。
var htmlToText = require('html-to-text');
var jade = require('jade');
const jadeTemplate = `doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) {
bar(1 + 5)
}
body
h1 Jade - node template engine
#container.col
if youAreUsingJade
p You are amazing
else
p Get on it!
p.
Jade is a terse and simple
templating language with a
strong focus on performance
and powerful features.`;
var html = jade.compile(jadeTemplate, {})({});
var text = htmlToText.fromString(html, {
wordwrap: 130
});
document.getElementById('text').value = text;
堆栈需要与16字节边界对齐,所以我假设编译器将保留32个字节。但是当我使用gcc x86-64编译这样的程序并读取输出程序集时,编译器会保留64个字节。
int main()
{
char buffer[20];
int x = 0;
buffer[0] = 'a';
buffer[19] = 'a';
}
给我:
..\gcc -S -o main.s main.c
为什么?当我编程程序集时,我总是只保留我需要的最小内存而没有任何问题。这是编译器的限制,它在评估所需的内存时有困难,还是有原因?
这是gcc -v
.file "main.c"
.def __main; .scl 2; .type 32; .endef
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp # RBP is pushed, so no need to reserve more for it
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $64, %rsp # Reserving the 64 bytes
.seh_stackalloc 64
.seh_endprologue
call __main
movl $0, -4(%rbp) # Using the first 4 bytes to store the int
movb $97, -32(%rbp) # Using from RBP-32
movb $97, -13(%rbp) # to RBP-13 to store the char array
movl $0, %eax
addq $64, %rsp # Restoring the stack with the last 32 bytes unused
popq %rbp
ret
.seh_endproc
.ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.2.0"
答案 0 :(得分:6)
编译器确实可以为自己保留额外的内存。
Gcc有一个标志-mpreferred-stack-boundary
,用于设置它将保持的对齐方式。根据{{3}},默认值为4,它应该产生16字节对齐,这是SSE指令所需的。
作为the documentation,您应该提供您的gcc版本和编译时选项(使用gcc -v
来显示这些选项)。
答案 1 :(得分:4)
因为您尚未启用优化。
如果没有优化,编译器不会尝试最小化生成代码中任何内容所需的空间或时间 - 它只是以最直接的方式生成代码。
如果您希望编译器生成合适的代码,请添加-O2
(或者甚至只是-O1
)或-Os
。
答案 2 :(得分:-2)
我总共需要24个字节。
编译器需要空间用于返回地址和基指针。当你处于64位模式时,那又是16个字节。总计40.将该数据舍入到32字节的边界,然后得到64。