有人可以帮我分割和 8086 intel 的微处理器吗?

Can someone help me with segmentation and 8086 intel's microprocessor?

我正在阅读有关intel 8086 架构的资料,但无法弄清楚以下有关分段的内容: 我知道段寄存器分别指向段并包含一个64kb 长段的基地址。但是谁计算并在哪一点设置段寄存器中的物理地址呢?另外,因为一个物理地址可以被多个 segment:offset 对访问并且段可以重叠,你怎么能确定你不会覆盖某些东西?我在哪里可以阅读更多相关信息?

一般来说,汇编程序只会使用偏移地址来访问逻辑地址。例如看这段代码:

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 位。因此,汇编程序会将地址 t运行 归为 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    ;

这样您就可以确定您正在访问正确数据段中的偏移量。

现在关于 'How do you make sure the code segment doesnt overlap the data segment',为什么不呢?当您的数据小于 64KB 的程序时,如果您的代码和数据段相同,这实际上是访问数据的最简单方法。

你怎么能确定你没有覆盖任何重要的东西?汇编程序无法帮助您,您必须检查自己是否正在写入的 segment:offset 地址已经包含数据。