我只是接近机器级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
我无法理解为什么它不起作用。我非常感谢任何帮助。
答案 0 :(得分:2)
如果以上是单个汇编程序文件,请将jmp 1000h:0000
更改为jmp 0FE0h:200h
,这将适当地补偿从ip
和[ORG 0]
一直累积的0x10000
寄存器偏移量仍然将控制转移到物理地址ds
。
除此之外,请在代码的第二部分中将cs
设置为0FE0h
(或{{1}})。
答案 1 :(得分:2)
"从软盘加载" part被编译为与其加载的基本偏移量不同的基本偏移量,您需要重新计算其地址
您也可以使用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,所以你实际上试图从你读的第二个扇区加载一些东西。在第二个加载扇区的开头是否有一些空白字符或零?