我正在阅读有关英特尔 8086 架构的信息,但无法弄清楚以下有关分段的内容:我知道段寄存器分别指向段并包含 64kb 长段的基地址。但是谁计算以及在哪一点设置段寄存器中的物理地址?另外,因为一个物理地址可以被多个段访问:偏移量对和段可以重叠,你怎么能确定你不会覆盖一些东西?我可以在哪里阅读更多相关信息?
1 回答
3
一般来说,汇编器只会使用偏移地址来访问逻辑地址。例如看这段代码:
start lea si,[hello] ; Load effective address of string
mov word [ds:si+10],0 ; Zero-terminate string after 10th letter
jmp $ ; Loop endlessly
; Fill rest of the segment with 0s
times 65536-($-$$) db 0x00
hello db "I'm just outside of the current segment. Hello!",0
汇编器将尝试计算 'hello' 与程序原点的偏移量。由于没有定义原点,因此将假定为 0x0。但是,在这种情况下,'hello' 的偏移量将是 0x10000,它不适合 16 位。因此,汇编器会将地址截断为 0x0000。它不会改变任何段寄存器。但是,它可能会发出警告,例如test.asm:1: warning: word data exceeds bounds
. 运行该程序时实际发生的情况是,该jmp $
行被零覆盖,因为 hello 的地址被环绕,CPU 只会开始执行零,这不是您打算做的。
当然,只有在代码段和数据段相同的情况下。现在谁保证是这样?真的没人。特别是因为我仍然不知道您正在为哪个平台编码。使用正确的值设置段寄存器完全是您的责任。最简单的方法是:
push cs ; Push address of code segment to stack
pop ds ; Pop address back into data segment
push cs ; Same for extra data segment
pop es ;
这样您就可以确定您正在访问正确数据段中的偏移量。
现在关于“你如何确保代码段不与数据段重叠”,为什么不呢?当您的程序的数据小于 64KB 时,如果您的代码和数据段相同,那么它实际上是访问数据的最简单方法。
你怎么能确定你不会覆盖任何重要的东西?汇编程序无法帮助您,您必须检查自己是否要写入的段:偏移地址已经包含数据。
于 2015-04-22T18:36:50.207 回答