相关疑难解决方法(0)

EBP帧指针寄存器的用途是什么?

我是汇编语言的初学者,并注意到编译器发出的x86代码通常在释放/优化模式下保持帧指针,当它可以使用EBP寄存器时.

我理解为什么帧指针可能使代码更容易调试,并且如果alloca()在函数内调用则可能是必要的.但是,x86只有很少的寄存器,并使用其中两个寄存器来保存堆栈帧的位置,当一个就足够了,对我来说没有意义.为什么即使在优化/发布版本中省略框架指针也是一个坏主意?

performance x86 assembly

87
推荐指数
3
解决办法
5万
查看次数

"enter"vs"push ebp; mov ebp,esp; sub esp,imm"和"leave"vs"mov esp,ebp; pop ebp"

enter和之间的区别是什么?

push ebp
mov  ebp, esp
sub  esp, imm
Run Code Online (Sandbox Code Playgroud)

说明?是否存在性能差异?如果是这样,哪个更快,为什么编译器总是使用后者呢?

以相若方式将leave

mov  esp, ebp
pop  ebp
Run Code Online (Sandbox Code Playgroud)

说明.

assembly stack

41
推荐指数
4
解决办法
1万
查看次数

和esp,0xfffffff0

我不完全理解下面的注释内容.我在SO和gcc手册中阅读了一些帖子,并了解到它是用于堆栈地址对齐但却无法理解它是如何做到的.代码如下所示:

(gdb) disas main
Dump of assembler code for function main:
   0x08048414 <+0>: push   ebp
   0x08048415 <+1>: mov    ebp,esp
   0x08048417 <+3>: and    esp,0xfffffff0 ; why??
   0x0804841a <+6>: sub    esp,0x10
   0x0804841d <+9>: mov    DWORD PTR [esp],0x8048510
   0x08048424 <+16>:    call   0x8048320 <puts@plt>
   0x08048429 <+21>:    mov    DWORD PTR [esp],0x8048520
   0x08048430 <+28>:    call   0x8048330 <system@plt>
   0x08048435 <+33>:    leave
   0x08048436 <+34>:    ret
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)

代码是gcc在linux上使用(版本4.6.3)生成的.谢谢.

x86 assembly

16
推荐指数
3
解决办法
6680
查看次数

汇编x86 - "离开"指令

据说"离开"指令类似于:

movl %ebp, %esp
popl %ebp
Run Code Online (Sandbox Code Playgroud)

我理解这movl %ebp, %esp部分,并且它用于释放存储的内存(如本问题中所讨论的).

但是popl %ebp代码的目的是什么?

c assembly

16
推荐指数
2
解决办法
4万
查看次数

6
推荐指数
2
解决办法
4055
查看次数

功能序言和结语由GCC优化删除

采取一个空的程序

//demo.c

int main(void)
{

}
Run Code Online (Sandbox Code Playgroud)

在默认优化时编译程序.

gcc -S  demo.c -o dasm.asm 
Run Code Online (Sandbox Code Playgroud)

我得到汇编输出为

//Removed labels and directive which are not relevant

main:

pushl   %ebp                  // prologue of main
movl    %esp, %ebp            // prologue of main
popl    %ebp                  // epilogue of main
ret
Run Code Online (Sandbox Code Playgroud)

现在在-O2优化时编译程序.

gcc -O2 -S  demo.c -o dasm.asm 
Run Code Online (Sandbox Code Playgroud)

我得到了优化的装配

main:

rep
ret
Run Code Online (Sandbox Code Playgroud)

在我最初的搜索中,我发现优化标志-fomit-frame-pointer负责删除序言和结尾.

我在gcc编译器手册中找到了有关该标志的更多信息.但是,由于手册的原因,我无法理解下面的原因,用于删除序言和结尾.

不要将帧指针保存在寄存器中以查找不需要的函数.

出于上述原因,还有其他方法吗?

"rep"教学的原因是什么,出现在-02优化?

为什么主函数,不需要堆栈帧初始化?

如果没有在主函数内设置帧指针,那么谁来完成这项工作呢?

它是由操作系统完成还是硬件的功能?

c optimization x86 assembly gcc

5
推荐指数
1
解决办法
1902
查看次数

GDB ret“无法访问地址处的内存”

简单地说:

  1. 栈顶($esp) = 0xbffff49c
  2. gdb 执行ret指令,该指令以Cannot access memory at address 0x90909094.

0x90909094当堆栈顶部的值是 时,gdb 尝试访问的原因是0xbffff49c什么?

随机信息(以防万一):

[----------------------------------registers-----------------------------------]
EAX: 0x5a ('Z')
EBX: 0xb7fbeff4 --> 0x15ed7c 
ECX: 0xbffff428 --> 0xb7fbf4e0 --> 0xfbad2a84 
EDX: 0xb7fc0360 --> 0x0 
ESI: 0x0
EDI: 0x0 
EBP: 0x90909090 
ESP: 0xbffff49c --> 0xbffff450 --> 0xdb31c031 
EIP: 0x80485dd (<greeting+113>: ret)
EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80485d0 <greeting+100>:    mov    DWORD PTR [esp],0x80487f4
   0x80485d7 <greeting+107>:    call   0x80483f0 …
Run Code Online (Sandbox Code Playgroud)

assembly stack gdb

4
推荐指数
1
解决办法
6023
查看次数

标签 统计

assembly ×7

x86 ×4

c ×2

stack ×2

cpu-registers ×1

gcc ×1

gdb ×1

optimization ×1

performance ×1

pointers ×1