汇编部分 .code 和 .text 的行为不同

2024-03-24

我是装配新手,从我所学到的.code.text,但是使用下面的代码会崩溃.code.

segment .data
    msg db "hello, world", 0xa
    len equ $ - msg

section .text
    global _start

_start:
    mov edx, len
    mov ecx, msg

    mov ebx, 1
    mov eax, 4
    int 0x80

    mov ebx, 0
    mov eax, 1
    int 0x80

nasm -f elf64 -o hello.o hello.s 
ld -s -o hello hello.o
hello, world

sed -i s/.text/.code/ ./hello.s
nasm -f elf64 -o hello.o hello.s 
ld -s -o hello hello.o
./stack.sh: line 8:  4621 Segmentation fault      (core dumped) ./hello

事实上,我不认为这有什么不同。为什么会出现这种情况?


在具有标准工具链的 Linux 上(GNU Binutilsld), .text是一个得到特殊处理的“特殊”节名称(默认情况下具有执行权限),但是.code不是。 (其他特殊部分包括.data(可写)和.bss(可写 nobits),并且所有默认对齐方式 > 1。)

section .text is the NASM ELF/Linux equivalent of Windows MASM .code directive, but that does not mean that Linux tools recognize a .code directive or section name1.

section .codesection xyz123;它只是使用默认值noexec nowrite.请参阅other底部的条目NASM 文档中的表格 https://www.nasm.us/xdoc/2.11.08/html/nasmdoc7.html#section-7.9.2.

Use readelf -a hello查看节(链接)和段(程序加载器)属性,明显缺少X任何地方。

脚注1:事实上,我认为Windows可执行文件仍然使用实际的节名称.text。至少是 GNUobjdump -d仍然说代码在.text部分。 所以面膜.code指令是切换到的快捷方式.text部分。


有趣的事实:如果您将其构建为 32 位代码(您应该因为它只使用 32 位int 0x80系统调用 https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code), 像这个案例 https://stackoverflow.com/questions/57316059/assembly-code-do-not-recognise-and-data使用过的section .code当错误地从 16 位 MASM 代码移植到 Linux NASM 时。
或者,如果您在较旧的内核上运行 64 位代码。

原因是没有明确指定PT_GNU_STACK请注意,内核对 32 位可执行文件使用向后兼容假设并使用READ_IMPLIES_EXEC这会影响每个页面:Linux 可执行文件 .data 部分的默认行为在 5.4 和 5.9 之间发生了变化? https://stackoverflow.com/questions/64833715/linux-default-behavior-of-executable-data-section-changed-between-5-4-and-5-9。较旧的内核甚至对于 64 位可执行文件也会这样做,在这种情况下,较新的内核仅使堆栈本身可执行。

Adding section .note.GNU-stack noalloc noexec nowrite progbits即使构建到 32 位可执行文件中,您的源代码也会出现应有的段错误。 (nasm -felf32 / ld -melf_i386 -o foo foo.o). See 这个答案 https://stackoverflow.com/questions/7863200/why-data-and-stack-segments-are-executable.

也可以看看当程序集文件包含在项目中时,来自 mmap 的意外执行权限 https://stackoverflow.com/questions/58260465/unexpected-exec-permission-from-mmap-when-assembly-files-included-in-the-project关于旧的情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汇编部分 .code 和 .text 的行为不同 的相关文章

  • 分配内存空间的宏

    我需要让一个汇编程序员来计算帕斯卡三角形 https en wikipedia org wiki Pascal 27s triangle 这样帕斯卡三角形的每一行都与其他行分开存储在内存中 我想做一个 但我不知道如何使用宏在汇编中做到这一点
  • 现代 x86 硬件不能将单个字节存储到内存中吗?

    说到 C 的并发内存模型 Stroustrup 的C 编程语言 第 4 版 第 1 节 41 2 1 说 就像大多数现代硬件一样 机器无法加载或存储小于单词的任何内容 然而 我的 x86 处理器已经有几年的历史了 它可以并且确实存储小于单词
  • 访问附加到 ELF 二进制文件的数据

    我有一个静态 ELF 二进制文件 它从 zip 文件中读取数据 为了简化分发 我想将 zip 文件附加到二进制文件中 如下所示 cat mydata zip gt gt mybinary 我知道这样做不会损坏 mybinary 但我不知道如
  • 我试图在 AAM 指令之后使用 AX 中存储的值将其除以 2,为什么它不适用于 2 位数字输出?

    英语不是我的母语 请原谅输入错误 我将在此处显示的代码是一项作业 我真的需要了解发生了什么事 我在 DosBox 0 74 和 TASM 汇编器中使用 Intel 8086 语法 当我必须除以 2 时 代码的问题在于三角形的面积 注意 程序
  • 当非特权用户运行 C/asm 程序时,会对 Linux 造成什么危害?

    我一直在考虑一种场景 让用户 可以是任何人 可能有恶意 提交在 Linux PC 我们称之为基准节点 上运行的代码 目标是为单线程例程创建一种自动化基准测试环境 假设一个网站向代理发布了一些代码 该代理将此代码交给基准节点 而基准节点仅与代
  • x86-64 Linux 中不再允许使用 32 位绝对地址?

    64 位 Linux 默认使用小内存模型 将所有代码和静态数据置于 2GB 地址限制以下 这确保您可以使用 32 位绝对地址 旧版本的 gcc 对静态数组使用 32 位绝对地址 以便节省相对地址计算的额外指令 然而 这不再有效 如果我尝试在
  • 推送 64 位 intel osx

    我想将 64 位地址压入堆栈 如下所示 asm pushq 0x1122334455667788 但我得到编译错误 我只能按以下方式推送 asm pushq 0x11223344 有人可以帮助我理解我的错误吗 我是装配新手 所以如果我的问题
  • 为什么 objdump 不显示 .bss、.shstratab、.symtab 和 .strtab 部分?

    我目前正在用 C 语言实现我自己的 objdump 实现 For my s选项 我必须显示 ELF 文件各部分的完整内容 我做得很好 但我显示的部分比 真正的 objdump 更多 事实上 它并没有输出 bss shstrtab symta
  • 如何获取 VESA BIOS 信息

    我正在跟踪Phil Opp 教程 https os phil opp com 关于用 Rust 编写一个操作系统 在稍微尝试了一下之后 我想在屏幕上显示真实的图形 我发现我应该从使用带有 VESA 的线性帧缓冲区开始 我在 osdev or
  • 汇编编程语言:程序仅当输入为 ESC 时退出,并在退出前要求确认(y/n),否则循环

    我只是汇编语言编程的初学者 我们的第一个任务是让程序仅在输入为 ESC 时退出 退出之前请求确认 y n 否则循环 我知道 ESC 在 ASCII 代码中具有等效值 但我对插入位置或是否需要添加更多内容感到困惑 请帮我 这是程序 model
  • 使用 gdb 调试反汇编库

    在Linux和Mac OS X中可以使用strapi和next来调试应用程序而无需调试信息 在 Mac OS X 上 gdb 显示在库内部调用的函数 尽管有时会在每个 stepi 指令中推进多个汇编程序指令 在 Linux 上 当我进入动态
  • 破坏/分解函数的函数

    我以前有过 here https stackoverflow com questions 4920610 c class function in assembly 已经表明 C 函数不容易用汇编表示 现在我有兴趣以一种或另一种方式阅读它们
  • 遍历内存编辑每个字节

    我正在编写汇编代码 提示用户输入一串小写字符 然后输出包含所有大写字符的相同字符串 我的想法是迭代从特定地址开始的字节 并从每个字节中减去 20H 将小写变为大写 直到到达具有特定值的字节 我对 Assembly 相当缺乏经验 所以我不确定
  • AVX512 掩码寄存器(k1...k7)的 GNU C 内联 asm 输入约束?

    AVX512 为其算术命令引入了 opmask 功能 一个简单的例子 上帝螺栓 org https godbolt org z P7xWD8 include
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • 为什么 Visual Studio 使用 xchg ax,ax

    我正在查看程序的反汇编 因为它崩溃了 并注意到很多 xchg ax ax 我用谷歌搜索了一下 发现它本质上是一个 nop 但是为什么 Visual Studio 会执行 xchg 而不是 noop 该应用程序是一个C NET3 5 64位应
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi

随机推荐