【问题标题】:Unable to use .bss section memory无法使用 .bss 段内存
【发布时间】:2018-04-13 16:44:26
【问题描述】:

我正在尝试将文件描述符存储在 .bss 内存中,用于从一个文件读取并写入另一个文件的基本 Linux 程序。我一直无法让它工作。

程序不返回错误,但不能正常工作。将文件描述符存储在堆栈上时,它可以正常工作。当我尝试在 gdb 中运行程序时,我得到以下输出:During startup program exited normally.

下面是简化版的代码:

.section .data

.equ SYS_EXIT,  1
.equ LINUX_SYSCALL, 0x80


.section .bss

.equ BUFFER_SIZE, 500
.equ DESCR_SIZE, 4
.lcomm BUFFER_DATA, BUFFER_SIZE
.lcomm BUFFER_IN_DESCR, DESCR_SIZE
.lcomm BUFFER_OUT_DESCR, DESCR_SIZE


.section .text


.globl _start
    _start:
    movl $7, BUFFER_IN_DESCR
    movl $SYS_EXIT, %eax
    movl $BUFFER_IN_DESCR, %ebx
    int $LINUX_SYSCALL

非常感谢任何帮助!

问题被编辑为最小、完整和可验证,正如 Peter 在 cmets 中提到的那样。

【问题讨论】:

  • movl $BUFFER_IN_DESCR, %ebx - AT&T 语法中的 $ 是直接常量 IIRC,因此这可能组装为使用内存地址而不是值加载 ebx。遍历gdb 中的代码,看看你自己,如果那部分内存包含你存储在那里的值(它可能会被缓冲区数据覆盖,如果你弄乱了要读取的块的大小或缓冲区地址),以及如何你的指令得到组装。如果由于缺少符号/等而无法在代码开头设置断点,请使用任何无效的断点 + 运行(我认为是b *0?) - 将在第一条指令处停止,删除 BP,步骤。
  • 我无法单步执行代码,当我在 gdb 中运行程序时,我收到以下消息:During startup program exited normally.。显然我的代码实际上并没有被执行。我试过b *0 也没用。
  • 获得一个有效的“hello world”示例,其中有很好的说明如何编译和运行,验证它在您的环境中是否有效。然后在gdb或其他调试器中进入它(我不使用gdb,所以我不知道还需要什么,但再次找到一些教程)。在你知道如何调试一个工作示例之后,回到你的代码(实际上是首先玩弄那个示例,以进行调试和理解它是如何工作的),要么弄清楚那个有什么不同,要么移动微小的部分从它到工作示例,直到它打破并弄清楚它是什么......
  • movl $BUFFER_IN_DESCR, %ebx 是 EBX 地址的 mov-immediate。也许您希望movl BUFFER_IN_DESCR, %ebx 从该符号引用的静态位置加载?这并不能解释为什么你不能调试你的程序,所以这不是你遇到的主要问题的minimal reproducible example。

标签: assembly x86


【解决方案1】:

在进一步解决这个问题后,问题是彼得在 cmets 中提到的立即寻址的错误使用。我仍然不确定为什么这会阻止我运行程序,并且只能假设这是由某种操作系统内存保护引起的。

【讨论】:

  • 很确定您只是做错了什么,除非您遇到了 GDB 错误或其他问题。我运行cat > foo.S 并将代码粘贴到问题中,然后运行gcc -g -m32 -static -nostdlib foo.S 和gdb ./a.out。使用b _start,我可以单步执行。如果我在没有-static 的情况下构建它,它也可以工作,使 32 位 PIE 可执行。如果我遗漏了-g。我在 Arch Linux 上安装了 GDB 8.1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 2012-09-29
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-02-07
相关资源
最近更新 更多