【问题标题】:How to locate a variable correctly in AT&T assembly?如何在 AT&T 汇编中正确定位变量?
【发布时间】:2012-09-20 22:41:32
【问题描述】:

我正在练习使用程序集(在 AT&T 语法和 gnu/gas 中)编写引导程序。小程序组装链接,然后复制到虚拟磁盘的第一个扇区。 BIOS 会将其加载到0000:7c00,问题就来了。 call hello 将在运行期间从 call 0010 转换为 call 7c10。但是movw $message, %as 不会被重新定位。 ax 仍然是 0026,而不是 7c26。结果是我无法在屏幕上制作Hello World。相反,0000:0026 处的一些随机数据将显示在屏幕上。

如何在引导过程中使其正确?我应该使用某些指令更改 asm 源代码吗?还是我应该更改我的链接脚本?

谢谢!

.text
.global     _start
.code16

_start:
movw    %cs, %ax
movw    %ax, %ds
movw    %ax, %es
call    hello
jmp     .

.org    0x10

hello:
movw    $message, %ax
movw    %ax, %bp
movw    $13, %cx
movw    $0x1301, %ax
movw    $0x000c, %bx
movb    $0, %dl
int     $0x10
ret

message:    
.ascii  "Hello, World!"

.org    0x01fe
.byte   0x55
.byte   0xaa

我使用以下汇编和链接脚本

as -o boot.o boot.s  
    //generate object code

ld -Ttext 0x0 -e _start -s -o boot.out boot.o  
    //relocate .text to 0x0
    //entry is _start

objcopy -O binary -j .text boot.out boot
    //copy .text section to boot

vboxmanage convertfromraw boot boot.vdi --format VDI
    //create vdi for virtual box

【问题讨论】:

  • 在代码的最开始使用一个组织。选择你想要的 0 或 0x7c00。如有必要,在链接时使用相同的值。适当修改代码,以便在代码访问其数据和调用函数之前,段和偏移量具有适当的值。
  • 另外,只使用 NASM 会容易得多。你不需要 ld 或 objcopy 。它可以直接将代码汇编成二进制文件(-f bin 选项)。
  • 另外,添加 ss/sp 初始化,所以你肯定不会在没有堆栈的情况下运行
  • 引导扇区加载代码设置这些值。根据规范,所有段寄存器都被清除,sp 设置为 7c00 并跳转到 7c00。但是,我不会假设每个 BIOS 实现或任何其他东西(如 RPL 引导加载程序)或遵循该规范的任何东西。用已知值加载 ss 和 sp 并没有太多的指令,对吧?为什么不这样做?
  • @Serge 是的,当然。我不应该在引导期间假设任何事情。明确指定任何内容可以控制一切。非常感谢!

标签: assembly ld bootstrapping att


【解决方案1】:

我发现主要问题在于您编译代码的方式。

让您的代码工作的正确步骤应该是:

as boot.s -c -o boot.o
ld --oformat binary --Ttext 0x7C00 -o boot.bin boot.o

请注意,正如其他人所说,我将--Ttext 0x7C00 参数传递给ld,以强制它将您的代码重新定位到该地址。

作为额外的建议,请尝试像这样构建您的代码:

.text
.global     _start
.code16

_start:
jmp stage1_start

...

stage1_start:

<your bootloader here>

请注意,这符合 BIOS 代码查看硬盘的方式,因为在 2 个字节(第一个跳转指令的长度)之后,您应该放置磁盘描述表。

此外,您可以使用类似 as 的语法重构您的最后一条指令,如下所示:

. = _start + 0x0200 - 2
.short 0x0AA55

. 变量是位置计数器。查看this page 以获取有关此计数器如何工作的更多信息(在ld 的上下文中,而不是as 的上下文中)。

希望这会有所帮助!

【讨论】:

  • 非常感谢您的详细回答以及您提供的链接!他们真的很有帮助。虽然我已经通过使用 -Ttext 0x7c00 选项解决了这个问题,但您的回答仍然提供了很好的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2019-09-18
  • 2021-02-19
相关资源
最近更新 更多