永发信息网

汇编:为什么esp被加两次?

答案:3  悬赏:10  手机版
解决时间 2021-08-19 15:23
这是原来的C函数:
void    input
(void)  {

        char    array[3];
        gets (array);
        printf (" %s\n", array);

        return;
}
这是gdb中的disas输出:
(gdb) disas input
Dump of assembler code for function input:
   0x080483b4 <+0>:     push   %ebp
   0x080483b5 <+1>:     mov    %esp,%ebp
   0x080483b7 <+3>:     sub    $0x18,%esp
   0x080483ba <+6>:     sub    $0xc,%esp
   0x080483bd <+9>:     lea    -0xb(%ebp),%eax
   0x080483c0 <+12>:    push   %eax                                                         
   0x080483c1 <+13>:    call   0x80482cc <gets@plt>                                         
   0x080483c6 <+18>:    add    $0x10,%esp                                                   
   0x080483c9 <+21>:    mov    $0x80484d0,%eax                                              
   0x080483ce <+26>:    sub    $0x8,%esp
   0x080483d1 <+29>:    lea    -0xb(%ebp),%edx
   0x080483d4 <+32>:    push   %edx
   0x080483d5 <+33>:    push   %eax
   0x080483d6 <+34>:    call   0x80482ec <printf@plt>
   0x080483db <+39>:    add    $0x10,%esp
   0x080483de <+42>:    leave 
   0x080483df <+43>:    ret   
End of assembler dump.
(gdb)
按照定义,生命了一个长度为3的数组,应该enter 4, 0才对,为什么通过减esp分配了那么多空间?又为什么要分两次分配呢?
一堆十六进制太晃眼了,还是贴个gcc的-S输出片段吧,差不多:
.LC0:                                                                                       
        .string " %s\n"
        .text
.globl input
        .type   input, @function
input:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        subl    $12, %esp
        leal    -11(%ebp), %eax
        pushl   %eax
        call    gets
        addl    $16, %esp
        movl    $.LC0, %eax
        subl    $8, %esp
        leal    -11(%ebp), %edx
        pushl   %edx
        pushl   %eax
        call    printf
        addl    $16, %esp
        leave
        ret


最佳答案
嗯,看起来,像是AMD的cpu上的编译结果。
第一次分配24个字节,是给这个函数的栈帧,至于为啥要这么多,是GCC自己决定的,留点空好区分吧,也可以避免点数组越界的错误。
第二次分配的12个字节,是给函数调用gets准备的,也是为了多留点空间,以备不测。至于为啥是这么多,每个gcc都不同,不同参数也可能不同。
全部回答
没有32个寄存器 只有32位寄存器算上调试寄存器 浮点寄存器 数目也不够32个找本汇编的书看看吧 这都是书上的原话~~~32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)6个段寄存器(ES、CS、SS、DS、FS和GS)1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)后面两类在反汇编中无用 (如果你不是逆向驱动的话)1、数据寄存器数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高;寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用; 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,但在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。2、变址寄存器32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。3、指针寄存器32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影响高16位的数据。寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们主要用于访问堆栈内的存储单元,并且规定:BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据;SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。
看看你是debug版本还是release版本 D版编译器自己加东西的
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
成大事者,
湖滨区三门峡GOO(千禧购物广场)怎么去啊,谁
友善福怎么扫,求友善福~ 10分
怎样才可以洒脱的忘记过去珍惜眼前呢?
体现父爱的句子和段落,关羽的忠义都表现在哪
彩虹岛游戏以外的一些问题
谁可以介绍个论坛网站!不要热门的!要人不多
歌唱兄弟的说唱歌,像龙井的归一样
PSP3000的 电子书阅读器怎么下载啊
五峰土家族自治县宜昌金山大酒店这个地址怎么
加一些糖用英文翻译
深圳沙井伟创力现在招聘不
没电脑自己可以开网店吗
怎样在手机上把魏晨《向日葵的微笑》的歌词转
找棕色的小壶歌曲和曲谱
推荐资讯
pk漫游如何选择远古套?
大陆行货诺基亚E5什么时候上市
曾都区爱游旅行(随州办事处)地址在什么地方,
济源市济源维雅中草药美颜养生馆地址有谁知道
Mylovewillgetyourhome的中文翻译
天心区长沙moo(海信广场店)地址在哪,我要去
一朵玫瑰花有多少花瓣,玫瑰花多少钱一朵
她的痛次!被我开一下玩笑就翻脸!是不是我错
六年级北师大寒假作业六年级上
白衣美人的诗句,需要形容美人的诗句。
谁能给我一个黑执事的电脑主题包啊
求问75老鼠身法高可以做单刷吗
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?