【问题标题】:x86 GNU Assembler Strange Change Seg Faultx86 GNU 汇编程序奇怪的更改段错误
【发布时间】:2014-07-19 06:53:54
【问题描述】:

下面的x86汇编代码汇编很好,它曾经在我学校的linux服务器上完美运行,但是在我的linux虚拟机(ubuntu 14.04)应用相同的代码时,突然导致分段错误。

堆栈约定是否改变了,这是 GNU 汇编程序的问题吗?我错过了什么备忘录? 我在 64 位机器上运行,这是构建操作系统主干的热身,所以我需要能够使用 16 位实数、32 位保护和 64 位模式都在同一个程序中。所以我想我真正需要的是关于使所有模式在同一个程序中有效的小细节。我知道在更改模式时使用 .code16/32/64 ,但我想我缺少什么(并且似乎在任何操作系统教程中都找不到,是如何在 64 位架构上执行此操作。

.code32
.text 
.global _start

_start:

    pushl $str1
    pushl $len1
    call print
    addl $8, %esp <-cleans up the stack pointer

exit:

    movl $1, %eax
    movl $0, %ebx
    int $0x80

print:

    pushl %ebp
    movl %esp, %ebp

    movl $4, %eax
    movl $1, %ebx
    movl 12(%ebp), %ecx <- This is where the Seg Fault occurs according to GDB
    movl 8(%ebp), %edx
    int $0x80
    popl %ebp
    ret

.data

str1 : .ascii "String1\n"

len1 =  . - str1

【问题讨论】:

  • 感谢 Dark,我不知道如何修复 linux 代码中的回车和换行。有什么简单的技巧吗?
  • 格式化工具栏上有一个按钮,或者:stackoverflow.com/editing-help
  • 非常感谢先生。
  • 我不明白问题的最后编辑。 64 位线程将具有 64 位堆栈,32 位线程将具有 32 位堆栈,而 16 位线程将具有 16 位堆栈。您只是无法在这些模式之间共享堆栈,因此您当前的代码只能在 64 位环境中运行。
  • 其实我目前的代码只能在32位环境下工作。我现在不断发展的问题和问题是:我如何组装一个引导扇区程序,它将 CPU 从其启动模式(16 位实数)引导到 32 位模式,它可以识别所有外围设备的存在,最后到将运行所有进程的 64 位模式?显然,这必须是可行的,因为这就是操作系统的制作方式,但是我如何在一个包含所有模式代码的程序的范围内正确地进行转换?

标签: linux assembly x86 segmentation-fault runtime-error


【解决方案1】:

我猜你有一台 64 位的机器,而你的程序显然是 32 位的。

我有一台 64 位机器,如果我用这个命令编译它,它会失败,和你一样:

$ gcc -nostdlib test.s

但是,如果我编译一个 32 位可执行文件:

$ gcc -nostdlib -m32 test.s

一切都很好。

请注意,您可能需要一些软件包才能在 64 位机器上编译 32 位程序(g++-multilib 或他们现在所说的任何名称)。

【讨论】:

  • 我确实有一台 64 位机器,但目前我正在学习如何编写一个功能齐全的引导扇区程序(为一个类构建一个 OS 框架),我需要能够在 16 位、32 位和 64 位模式之间传输而不会出现段错误。换句话说,我确实需要标准库 EVENTUALLT,所以没有它我不能只编译成品(我不认为......)。这里有人是这方面的专家吗?
  • 不清楚你在问什么。这回答了直接的问题 - 您的代码是 32 位 x86 程序集,因此需要针对 32 位 x86 模式进行编译。如果您需要编写更多代码/将其移植到 x64 模式,那似乎是一个不同的问题。在编写引导扇区程序时,您也不太可能希望/能够使用任何 gcc 启动或系统库代码。
猜你喜欢
  • 1970-01-01
  • 2015-10-26
  • 2022-10-15
  • 1970-01-01
  • 2014-05-11
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多