YASM [symbol + $$]有效地址在平面二进制中太复杂

问题描述 投票:1回答:1

org 0x7c00是在平面二进制文件中获取正确绝对地址的正常方法,但是我很好奇我希望使用的另一种方法。

我尝试使用section boot vstart=0x7c00 align=1告诉YASM正确的内存地址,而在另一部分中使用symbol则使用了start=300

mov [symbol+$$], register

[yasm -fbin boot.asm在该行上给出error: effective address too complex

根据我的理解,symbol+$$应该可以处理成一个数字(而不是一个段+偏移),对吗?如果我错了,请告诉我,但是如果我是正确的,那么为什么YASM告诉我地址​​太复杂了?

是否还有另一种方法可以使用start=和/或vstart=代替org并且仍然获得正确的绝对寻址?

使用[symbol]无效;组装为[0000]]的绝对地址


之所以这样做,是因为我有一个用于重定位自身的引导加载程序的二进制机器代码,但是在重定位之前,它在一些符号中存储了一些值(例如,传入的引导驱动器dl

YASM支持带有“节”的二进制程序,该节可以具有不同的寻址偏移,所以我要做的是代码设置,其中MBR是第一个扇区的前300个字节,变量存储在300个字节之后,在第446个字节之前,我想使用此方法,以便可以使用技术上其他节中的变量,但可以相对于当前节偏移量进行复制。

这是我要执行的操作的简化示例:

; example.asm
; yasm -fbin example.asm

%define virtual(_name, _offset) section _name vstart=_offset align=1
%define absolute(_name, _offset) section _name start=_offset align=1

virtual(boot, 0x7c00) ; Virtual Offset of 0x7c00 (in-file offset of 0)
start:
    ; This is just an example
    ; There isn't going to be much here.
    mov [boot_drive+$$], dl

    cli 
    hlt

absolute(vars, 300) ; Virtual AND in-file offset of 300

boot_drive db 0

org 0x7c00是在平面二进制文件中获取正确绝对地址的正常方法,但是我很好奇我希望使用的另一种方法。我尝试使用部分引导vstart = 0x7c00 align = 1到...

assembly x86-16 memory-address bootloader yasm
1个回答
2
投票

您的基本问题是,您实际上并没有添加两个数字,而是添加了两个符号,并且汇编程序通常不允许这样做。这是因为目标文件格式无法将两个符号的添加表示为重定位,这是因为添加两个符号实际上没有多大意义。在这种情况下,您生成的二进制文件不支持重定位,因此汇编程序可以发明自己的虚拟重定位来处理此问题,显然,YASM并没有将其作为一般规则的例外来实现。 >

为什么汇编程序不允许添加符号


1
投票

YASM似乎挺好用,但是在临界表达式中使用$-$$时,NASM似乎更为理智(例如节的start选项)。在玩了一段时间之后,我有理由不使用YASM。

© www.soinside.com 2019 - 2024. All rights reserved.