【问题标题】:Can't modify memory using 32bit assembler无法使用 32 位汇编器修改内存
【发布时间】:2011-04-09 11:31:52
【问题描述】:

我正在使用 NASM 来组装我的汇编代码。我组装的代码是这样的:

[BITS 32]
[ORG 0]
  jmp 07c0h:start

  testvar db 0, 0, 0, 0, 0, 0, 4, 8, 15, 16, 23, 42

start:
  mov byte [testvar], 47

  hang:
    jmp hang

  times 510-($-$$) db 0
  dw 0AA55h

我在另一段代码中遇到了问题,我注意到我无法修改内存,所以我编写了这段代码来测试是否确实如此。它是!我将汇编的机器代码复制到软盘的第一个扇区,程序运行(我使用了 MS VirtualPC)。我检查了分配给 Virtual PC 的 RAM 内存并搜索了数字 4 8 15 16 23 42,这样我就可以找到二进制代码的复制位置。数据的第一个字节未被触及。为什么会这样?

【问题讨论】:

  • 您使用的是哪个操作系统?你怎么知道你的汇编代码正在被加载和运行?您可以使用调试器单步执行吗?它在哪个地址加载?
  • 我使用的是 Windows XP。我知道代码已运行,因为如果我省略“[BITS 32]”,它就可以正常工作。 (为什么不加载它?)它加载到通常加载引导扇区的位置,到 7c00h。我该如何调试它?
  • 一点点语言挑剔汇编器是一个汇编你的汇编源代码的程序:)

标签: memory assembly x86 32-bit nasm


【解决方案1】:

除了bits 32 的引导加载程序代码错误之外,另一个问题是您没有将ds 设置为任何内容,因此它将保留最后放入的任何ROM-BIOS。您希望 mov ax, 7C0h \ mov ds, ax 修复该问题(使用 org 0 时)。

【讨论】:

    【解决方案2】:

    在源文件中设置“BITS 32”只会影响汇编器输出的操作码。

    要执行 32 位代码,您需要将处理器模式更改为 32 位保护模式。通常,当您移动到第一个玩具引导扇区之外时,您将分多个步骤进行内核加载。首先是 16 位引导扇区,具有大小限制。这会加载一个 16 位引导加载程序,进而可以设置保护模式。一些设计将这个 16 位部分保持最小,并进一步使用 32 位引导加载程序来加载内核,其他设计直接从 16 位引导加载程序加载内核。

    我建议你看看http://wiki.osdev.org/Main_Pagehttp://www.asmcommunity.net/http://board.flatassembler.net/:)

    【讨论】:

    • 我已经访问过 osdev.org,感谢其他地址。 ;-)
    【解决方案3】:

    简单的答案是相同的代码汇编为 32 位与汇编为 16 位的代码不同。引导扇区代码(以及所有加载的代码)在 16 位实模式下运行,直到切换 CPU 模式。

    满意的答案是列表显示了差异。

                                                    [BITS 16]
    0000000C: C6 06 00 00 2F                          mov BYTE [testvar], 47
    

    与 32 位相同的代码

                                                    [BITS 32]
    0000000C: C6 05 00 00 00 00 2F                    mov BYTE [testvar], 47
    

    以 16 位运行时的等效代码

                                                    [BITS 16]
    0000000C: C6 05 00                                mov BYTE [di], 0
    0000000F: 00 00                                   add [bx+si], al
    00000011: 00 2F                                   add [bx], ch
    

    【讨论】:

    • 那你是说如果我要从我的 16 位引导扇区加载一个 32 位代码并跳转到它,那 32 位代码会正常工作,而引导扇区本身是 32 位则不会?
    • 没有。首先,无论您加载什么,都必须更改为 32 位模式。
    【解决方案4】:

    我的理解是 PC 兼容机器都以 16 位模式启动(出于兼容性原因)。 所以在我看来,您需要从 [BITS 16] 开始,即使第一条指令是跳转到 32 位模式并且紧随其后的是 [BITS 32]。 见NASM: Mixing 16 and 32 Bit Code

    我对软盘启动过程有点模糊。 您确定代码位于实际执行的位置吗? 是否可以单步执行该代码?

    【讨论】:

    • 引导扇区始终加载到物理地址 0x7C00,但并非所有 BIOS 都同意用于引用此地址的 CS:IP(请记住 16 位实模式寻址的古怪方式:seg*16+的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    相关资源
    最近更新 更多