【问题标题】:NASM. Square brackets return relative location. How to find absolute?NASM。方括号返回相对位置。如何找到绝对?
【发布时间】:2020-04-06 06:43:34
【问题描述】:

我正在尝试用电传打字机打印符号。 这是一段代码:

mov al, [smb]
int 0x10

smb: db "X"

但事实证明,这显示了来自内存而不是来自该位置的任意符号。似乎 [] 返回符号的相对地址。这可能是意料之中的,但问题是:我怎样才能找到绝对地址? 我正在使用 QEMU-i386,与标准 NASM 组装。

附:在查看了与 NASM 相关的其他问题后:请不要告诉我去查看 NASM 的文档,因为这里有很多人问了很多关于 C# 的简单问题,但这些问题并没有发送给 Richter。

【问题讨论】:

  • 您应该提供Minimal, Reproducible Example
  • mov al, [smb]smb 处的字节(本例中为X)移动到AL。这可能是您想要做的。我假设您已将 0x0e 移至 AH 以通过 BIOS 服务 int 10h 进行 TTY 输出调用。您可能想在 int 0x10 和下面的数据之间放置一个无限循环或其他东西,这样您就不会失败并开始将代码作为数据执行。但如果我不得不猜测,您的问题可能是 DS 段寄存器指向错误的段。如果您展示了所有代码,那将有所帮助。我猜您可能是在某种引导加载程序或第一阶段执行此操作?
  • 另一种可能性是您没有根据代码的预期设置 ORG 语句。例如,在 bootloader 中,我通常在 NASM 文件的顶部使用 ORG 0x7c00,然后在引导加载程序代码的顶部,我将 DS 设置为 0,使用类似 xor ax,ax mov ds, ax
  • 谢谢!即使没有将 DS 设置为 0x00,调用 ORG 0x7c00 也有效。是的,我正在为一个爱好项目构建一个简单的引导扇区

标签: assembly nasm x86-16 qemu real-mode


【解决方案1】:

对于 64 位代码;默认是绝对寻址,要获得 RIP 相对寻址,您可以使用 mov al, [rel smb] 之类的东西。然而;可以使用DEFAULT REL 指令更改默认值;在这种情况下,如果您想要绝对寻址,您可以使用 mov al, [abs smb] 之类的东西。

适用于 16 位和 32 位代码;绝对寻址是唯一的选择(忽略在某些跳转和调用中出现的“绝对地址编码为相对位移”可能不必要的混淆,这对于mov al, [smb] 无关紧要)。

对于这两种情况(16 位和 32 位代码,以及 64 位代码); “绝对寻址”实际上是从段基址的绝对偏移量。例如,mov al, [smb] 将隐式使用DS 段,因此如果 DS 段的基地址不为零(这仅适用于 32 位和 16 位代码 - 仅适用于 64 位代码 FS 和GS 可以有一个段基址)实际的绝对地址将是“段基址 + 绝对偏移量”。如果段基数为零,则可以忽略(“段基数+绝对偏移量”=“0+绝对偏移量”=“绝对偏移量”)。

当然,如何确定绝对偏移量取决于它在哪个节以及节开始的位置;其中(取决于输出文件格式 - 平面二进制文件与目标文件)取决于 org 指令、节定义或链接器。

【讨论】:

    【解决方案2】:

    你要找的指令是Load Effective Address:What's the purpose of the LEA instruction?

    【讨论】:

    • 这有关系,但这不是解决问题的方法——我只需要绝对地址
    • 这是 LEA 计算的。
    • @AlexeyKhrenov 请注意,LEA 仅处理 seg:off 地址的“偏移”部分。如果您没有平面内存模型和/或您没有正确使用org 告诉汇编程序加载程序的位置,LEA 将无济于事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    相关资源
    最近更新 更多