Assembly i386实模式。关于从内存加载数据的一些问题

Assembly i386实模式。关于从内存加载数据的一些问题,assembly,x86,nasm,real-mode,Assembly,X86,Nasm,Real Mode,我刚刚接近机器级x86编码,所以请原谅我的问题太琐碎了。下面的代码是一个简单的引导加载程序。它将软盘的某些扇区转储到内存中,然后跳转到加载的代码。在加载的代码中,我试图从内存变量中读取,但没有成功,如注释中所述 [ORG 0] jmp 07C0h:start ; Goto segment 07C0 start: ; Update the segment registers mov ax, cs

我刚刚接近机器级x86编码,所以请原谅我的问题太琐碎了。下面的代码是一个简单的引导加载程序。它将软盘的某些扇区转储到内存中,然后跳转到加载的代码。在加载的代码中,我试图从内存变量中读取,但没有成功,如注释中所述

    [ORG 0]

            jmp 07C0h:start     ; Goto segment 07C0

    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax


    reset:                      ; Reset the floppy drive
            mov ax, 0          
            mov dl, 0          
            int 13h            
            jc reset         


    read:
            mov ax, 1000h       ; ES:BX = 1000:0000
            mov es, ax          
            mov bx, 0           

            mov ah, 2           ; Load disk data to ES:BX
            mov al, 5           ; Load 5 sectors
            mov ch, 0           ; Cylinder=0
            mov cl, 2           ; Sector=2
            mov dh, 0           ; Head=0
            mov dl, 0           ; Drive=0
            int 13h             ; Read!

            jc read             ; on error


            jmp 1000h:0000      ; Jump to the program


    times 510-($-$$) db 0
    dw 0AA55h

       ;     ==  Loaded code from second floppy sector  ==
prog:
        mov     ah,     0x0E       ; Prints a char. This one works: the '-'
        mov     al,     '-'        ;   is printed.
        mov     bx,     0
        int     10h

        mov     bx,     0 
a:                                 
        mov     al,     [L1+bx]    ; Should read from L1 and print out chars.
        inc     bx                 ;   But it prints only white spaces. Why?
        int     10h
        cmp     bx,     10
        jz      h
        jmp a

        cli
        hlt

        L1 db "0123456789"        ; my string

我不明白为什么它不起作用。非常感谢您的帮助。

如果以上是一个汇编文件,请将
jmp 1000h:0000
更改为
jmp 0FE0h:200h
,这将适当补偿从
[ORG 0]
一路累积的
ip
寄存器偏移量,并将控制权转移到物理地址
0x10000


除此之外,在代码的第二部分将
ds
设置为
cs
(或设置为
0FE0h
)。

如果上面是一个汇编文件,请将
jmp 1000h:0000
更改为
jmp 0FE0h:200h
,这将适当补偿从
[ORG 0]
一路累积的
ip
寄存器偏移量,并且仍然将控制权转移到物理地址
0x10000

除此之外,在代码的第二部分中,将
ds
设置为
cs
(或设置为
0FE0h
)。

从软盘加载的部分是为不同于其加载的基偏移量编译的,您需要重新计算其地址

您还可以使用
ORG 7C00h
来避免跳转,不同之处在于您的片段将是0而不是07C0h

您可以将新偏移量计算为[L1 prog],也可以对代码重新排序:

            jmp 1000h:000Ah      ; Jump to the program
....
L1          db "0123456789"        ; my string
prog:
        mov     ah,     0x0E   

...
        mov     al,     cs:[bx]
我没有要测试的汇编器,但你明白了——去掉对浮动地址的需要,把它放在开头

我粗略估计你们在1000H段的实际偏移量大约是32 ish,这就是你们翻译的L1的大致位置。相反,L1的编译时间被计算为大约550小时,所以实际上您正试图从读取的第二个扇区加载一些内容。第二个加载扇区的开头是否有一些空白字符或零?

编译“从软盘加载”部分时,其基址偏移量与加载到的基址偏移量不同,您需要重新计算其地址

您还可以使用
ORG 7C00h
来避免跳转,不同之处在于您的片段将是0而不是07C0h

您可以将新偏移量计算为[L1 prog],也可以对代码重新排序:

            jmp 1000h:000Ah      ; Jump to the program
....
L1          db "0123456789"        ; my string
prog:
        mov     ah,     0x0E   

...
        mov     al,     cs:[bx]
我没有要测试的汇编器,但你明白了——去掉对浮动地址的需要,把它放在开头



我粗略估计你们在1000H段的实际偏移量大约是32 ish,这就是你们翻译的L1的大致位置。相反,L1的编译时间被计算为大约550小时,所以实际上您正试图从读取的第二个扇区加载一些内容。第二个加载扇区的开头是否有一些空白字符或零?

DS设置为CS,开头为0,如果“从软盘加载”与之前的代码加载在同一地址,则会给出正确的地址it@StenPetrov不。我的意思是,当执行代码的第二部分时,
ds
。在那里时,
cs
=
ds
。我试图设置数据段寄存器。我在
prog:
之后添加了以下内容:
mov-ax,1000h
mov-ds,ax
,但没有任何更改。@mghis ds是否指向CS段并不重要。你有一个组织,它是0,地址L1是编译时计算出来的,很可能与你加载它的实际地址不同disk@StenPetrov哦,我想我明白了。以上是一个源文件,而不是两个。我假设它是2.DS,设置为CS,开始时是0,如果“从软盘加载”加载的地址与之前的代码相同,则会给出正确的地址it@StenPetrov不。我的意思是,当执行代码的第二部分时,
ds
。在那里时,
cs
=
ds
。我试图设置数据段寄存器。我在
prog:
之后添加了以下内容:
mov-ax,1000h
mov-ds,ax
,但没有任何更改。@mghis ds是否指向CS段并不重要。你有一个组织,它是0,地址L1是编译时计算出来的,很可能与你加载它的实际地址不同disk@StenPetrov哦,我想我明白了。以上是一个源文件,而不是两个。我假设是两个。@AlexeyFrunze哦,我现在明白了事实上,第一个扇区用零填充,直到到达第二个扇区为止。然后它打印出那些记忆。好吧,我试着把
[L1+bx]
改成
[L1 prog+bx]
,它成功了,但只有在按照另一个答案设置ds寄存器之后。现在我在接受答案方面遇到了麻烦。:-)因此,段选择器和偏移都是错误的。谢谢你的帮助@哦,我现在明白了,事实上,第一个扇区用零填充,直到第二个扇区到达。然后它打印出那些记忆。好吧,我试着把
[L1+bx]
改成
[L1 prog+bx]
,它成功了,但只有在按照另一个答案设置ds寄存器之后。现在我在接受答案方面遇到了麻烦。:-)因此,段选择器和偏移都是错误的。谢谢你的帮助!只是想澄清一下,上面是一个源文件还是两个?你能给我们实际的代码吗?
h
标签丢失,没有它,此代码无法汇编。请检查我答案中的最后一句话update@Frunze:代码都在一个文件中。很抱歉
h
,它是
cli
之前的一个标签,但我在帖子中删除了它,以使其更小、更可读,而没有注意到它被
jz
引用。只是澄清一下,上面的是一个标签吗