Assembly 在汇编x86实模式下寻址是如何工作的?为什么标签返回不同的值?

Assembly 在汇编x86实模式下寻址是如何工作的?为什么标签返回不同的值?,assembly,x86,nasm,bootloader,real-mode,Assembly,X86,Nasm,Bootloader,Real Mode,我有两种版本的引导加载程序代码(它应该在512b引导加载程序代码之后移动1kb堆栈)。 开始物理地址始终为0x7c00(标签“开始”)。BIOS将引导加载程序代码复制到RAM中。 当我使用“MOV SP,启动+1024+512”时: SP将是0x7c00+1024+512,因为物理地址应该是SS:SP=0 。。。始终转到地址0x7c00。它将计算 在分段内存模型中,您不应该只考虑有效(物理)地址,还必须始终将地址视为实模式下的(16+16)位值或16位保护模式下的(16+32)位值或32位保护模

我有两种版本的引导加载程序代码(它应该在512b引导加载程序代码之后移动1kb堆栈)。 开始物理地址始终为0x7c00(标签“开始”)。BIOS将引导加载程序代码复制到RAM中。 当我使用“MOV SP,启动+1024+512”时:

  • SP将是0x7c00+1024+512,因为物理地址应该是SS:SP=0 。。。始终转到地址0x7c00。它将计算

    在分段内存模型中,您不应该只考虑有效(物理)地址,还必须始终将地址视为实模式下的(16+16)位值或16位保护模式下的(16+32)位值或32位保护模式下的(16+32)位值

    假设您的程序包含指令
    mov al,cs:[100h]


    此指令将从地址
    CS:0x100
    读取一些字节,该地址实际上是
    (你能把重点放在这一点上吗?这里似乎有至少10个问题,大约有9个太多了,我甚至不知道如何在不写一本关于8086内存体系结构的书的情况下开始回答。但也许是有帮助的。一些生物传感器会将CS:IP设置为
    0000:7c00
    ,其他设置为
    07c0:0000
    。实验室会发生什么el
    start
    独立于此,由您在源代码中为
    org
    选择的值决定。您确实需要将段和偏移分开,因为CPU就是这样做的;它只在最后一个阶段将它们转换为物理地址。
    jmp main
    很可能是一个相对的问题或“短”跳转。汇编程序计算
    jmp main
    指令本身和标签
    main
    之间的字节数,并将差异编码到地址中。执行时,CPU将此值添加到程序计数器IP,而不使用CS。因此,无论段寄存器如何设置,它都能正常工作,并且不受影响呃,代码恰好加载到内存中。谢谢@NateEldredge您回答了我所有的问题=)额外感谢jmp。我忘记了这个机制。更正:它是
    jmp main
    之后的下一条指令与标签
    main
    之间的字节数。对于短跳转和近直接跳转都是如此,问题是这个差分适合8位符号扩展立即数还是16位。
    mov SI, main
    lodsb ;write data from main to AL
    
    [bits 16]
    [org 0x7c00]
    start:  ;offset= 0x7c00
    jmp main
    db    "Some data" ;actually fake BIOS Parameter Block(BPB)
    main: 
    mov ax, 0 
    mov ds, ax ; data segment =0.
    mov ss, ax ; stack segment = 0
    mov sp, start+1024+512 ;stack pointer = 0x7c00+1024+512
    
    [bits 16]
    [org 0x0000]
    start:  ;offset= 0x0000
    jmp main
    db    "Some data" ;actually fake BIOS Parameter Block(BPB) 
    main:
    mov ax, 0x07c0 
    mov ds, ax ; data segment =0x07c0.
    mov ss, ax ; stack segment =0x07c0.
    mov sp, start+1024+512 ;stack pointer = 0+1024+512