繁体   English   中英

为什么我的汇编程序转储中的地址与寄存器的地址不同?

Why do the addresses in my assembler dump differ from the addresses of registers?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我有一个非常基本的程序,我用它编译

gcc -m32 -g -o hello32.out hello.c

当我在 gdb 中运行 disassemble main 时,我得到以下输出:

0x0000051d <+0>:    lea    ecx,[esp+0x4]
0x00000521 <+4>:    and    esp,0xfffffff0
0x00000524 <+7>:    push   DWORD PTR [ecx-0x4]
0x00000527 <+10>:   push   ebp
0x00000528 <+11>:   mov    ebp,esp
0x0000052a <+13>:   push   ebx
0x0000052b <+14>:   push   ecx
0x0000052c <+15>:   sub    esp,0x10
0x0000052f <+18>:   call   0x420 <__x86.get_pc_thunk.bx>
0x00000534 <+23>:   add    ebx,0x1aa4
0x0000053a <+29>:   mov    DWORD PTR [ebp-0xc],0x0
... [truncated for brevity]

然而,当我跑

(gdb) break main
(gdb) run
(gdb) info register eip

我得到

eip            0x5655553a   0x5655553a <main+29>

为什么 main+29 在汇编程序转储中显示为 0x0000053a 而在给出 eip 地址时显示为 0x5655553a?

1 个回复

默认情况下,您的 GCC 使 PIE 可执行文件,因此文件中没有固定的基地址(反汇编显示它相对于 0,即偏移量而不是绝对地址)。

一旦内核的 ELF 程序加载器从可执行文件创建了一个正在运行的进程(并选择了一个虚拟地址作为基址),GDB 就可以向您显示实际的运行时虚拟地址。 (例如starti开始运行它,然后disas my_func获得该进程中的一个有效的地址; GDB禁用ASLR所以这将是相同的只有GDB下运行,或禁用ASLR的的具体运行的其他方式每次过程或系统范围。)

使用-fno-pie -no-pie构建以获取位置相关的可执行文件,其中运行时地址可从可执行文件元数据中获知。 (对于 i386 代码,您绝对应该更喜欢-fno-pie :如果没有 RIP 相对寻址,位置无关代码的额外性能/代码大小成本明显低于 x86-64。)


相关: x86-64 Linux 中不再允许 32 位绝对地址? 有关 PIE 的更多信息(32 位和 64 位 x86,以及一般情况。)

GDB - 断点地址与此类似,但不完全重复。

1 解除引用寄存器地址的汇编程序分段错误

我的x86汇编(AT&T)有问题。 因为我需要在汇编器中实现数组查找,所以我在寄存器%ebx中拥有数组的第一项(例如arr [0]),并且为了指向arr [1],例如,我写道: 问题是,当我尝试获得ebx的地址时出现了段错误,这很奇怪,因为我可以毫无问题地获得ebx的值(arr [ ...

2 汇编程序:使用寄存器库计算内存地址

我有这个简单的汇编程序命令: 我的问题是我需要知道这个命令真正读取了什么具体地址。 我发现了很多关于汇编器寻址模式的文档,但没有关于寄存器的注释:符号。 有人可以解释一下地址计算背后的数学吗? ...

3 汇编程序中eax寄存器的值

我正在完成与c编程和汇编语言有关的作业。 这是简单的c程序: 它的优化组装是 我想知道汇编后这一行代码后eax寄存器的值 我知道在程序集中添加整数时,它将结果存储在目标位置。 当我们相乘时,它存储在eax中。 因此,如果我调用函数multiple(3,8),则该行之 ...

4 汇编程序和C编程linux -m32(汇编程序中寄存器的字符字节)

我对汇编编程非常陌生,我用C语言编写了一个函数,该函数需要在汇编中调用另一个函数。 似乎寄存器想要返回四个字符(字节)而不是一个,这正是我想要的。 跳转后请忽略代码,因为我跳转只是跳过了这部分代码,直到我使之正常工作为止。 实际上,这应该是我自己在C语言中sprintf简化版本的一 ...

5 使用fasm汇编程序将寄存器值以汇编语言移动到存储器地址时遇到问题吗?

我对这件事真的很困惑。 我一直在遵循针对x86处理器的汇编程序设计书籍,并且正在阅读有关mov指令及其工作方式的信息。 因此,作者说以下指令是有效的mov mem,reg .....基本上将寄存器值移动到存储器地址。 现在,这是我尝试过的,并且我不断收到称为无效操作数的错误。 有人可 ...

6 2个汇编程序如何使用相同的寄存器

我正在学习assembly 8086并且我了解assembly程序经常使用寄存器,那么在同一时间运行的两个assembly程序如何可以使用同一寄存器而不会相互中断。 我以为一台PC可以有几套寄存器,例如100套,所以每个程序都可以使用一个寄存器而不会中断其他程序。 好吧,这只是一个猜测。 ...

8 汇编程序使用段寄存器

最近在写汇编,我写的程序在DOSBox下运行没有任何问题。 现在我需要将相同的程序移植到使用 DOS 的真实计算机中,但出现了一些问题。 首先,在 DOSBox 下,我使用 ML 进行编译,但是在真正的 PC 上,一旦我输入 ML,它就会说: 该程序不能在 DOS 模式下运行。 因此,我 ...

9 在C中嵌入汇编程序,编译器为您查找寄存器

将汇编代码嵌入到C / C ++程序中时,可以通过使用push指令保存寄存器(或指定编译器的clobber列表支持它)来避免破坏寄存器。 如果你包括汇编内联并希望避免推送和弹出破坏寄存器的开销,有没有办法让gcc为你选择寄存器(例如它知道它们中没有有用的信息)。 ...

10 x86_64汇编程序中RBP寄存器的用途是什么?

所以我正在尝试学习一点装配,因为我需要它用于计算机体系结构类。 我写了一些程序,比如打印Fibonacci序列。 我认识到每当我编写一个函数时,我都会使用这三行(正如我从gcc生成的汇编代码与它的C等价物进行比较所学到的): 我有2个问题: 首先,为什么我需要使用%rb ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM