【发布时间】:2016-09-15 10:26:58
【问题描述】:
我正在尝试编写一个极其简单的 MBR,以开始学习如何编写 MBR/内核。这就是我到目前为止所拥有的(从其他 MBR 的片段创建)。我使用 nasm 然后 ld 链接得到的二进制文件与仅使用 nasm 进行链接有点不同,但这似乎不是问题。
我最初是从jmp 0:continue 开始,但它似乎跳到0000:7c22(或单独使用nasm 的001d...我相信我没有指定它从7c00 开始)但我想跳到@ 987654325@或:7a1d,重定位代码的地址。我尝试只使用jmp continue,然后如下面未注释的那样,将堆栈指针添加到 continue 指针,将其推送并 ret。当 dd'ed 到我的第一个扇区时,我得到的只是一个闪烁的光标。任何帮助表示赞赏。
; nasm+ld nasm comment
global _start
_start:
xor cx, cx ; 6631c9 31c9 Set segment registers to zero
mov es, cx ; 8ec1 8ec1
mov ds, cx ; 8ed9 8ed9
mov ss, cx ; 8ed1 8ed1
mov sp, 0x7A00 ; 66bc007a bc007a Stack
mov di, sp ; 6689e7 89e7 Bottom of relocation point
mov esi, _start ; be007c0000 66be00000000
cld ; fc fc
mov ch, 1 ; b501 b501 cx = 256
rep movsw ; f366a5 f3a5 Copy self to 0:7A00
;----------------------------------------------------------------------------------------------------------------------
xor eax,eax
mov ax, sp
add ax, continue
;jmp 0:continue ; ea227c00000000 ea1d000000 near JMP to copy of self
; or
;jmp continue ; (eb00)
push eax
ret
;----------------------------------------------------------------------------------------------------------------------
continue:
sti ; fb fb
ERROR:
mov esi, errormsg ; be3b7c0000 (be36) 66be36000000 Error Message loc
mov ah, 0x0E ; b40e b40e
mov bx, 7 ; 66bb bb0700
disp:
lodsb ; ac ac
cmp ah, 0x00 ; 80fc00 80fc00
je end ; 7404 7404
int 10h ; cd10 cd10
jmp disp ; ebf6 ebf6
end:
nop ; 90 90
jmp end ; ebfd ebfd infinte loop
errormsg db 10,'YOU MESSED UP.',13,0
times (0x1b8 - ($-$$)) nop ; 90 90 Padding
UID db 0xf5,0xbf,0x0f,0x18 ;Unique Disk ID
BLANK times 2 db 0
PT1 db 0x80,0x20,0x21,0x00,0x0C,0x50,0x7F,0x01,0x00,0x08,0x00,0x00,0xb0,0x43,0xF9,0x0D ;First Partition Entry
PT2 times 16 db 0 ;Second Partition Entry
PT3 times 16 db 0 ;Third Partition Entry
PT4 times 16 db 0 ;Fourth Partition Entry
BOOTSIG dw 0xAA55 ;Boot Signature[/code]
【问题讨论】:
-
看起来您的链接器正在生成 32 位代码,这对于引导扇区是错误的。 (虽然我从来没有听说过
ld实际上在说明之前插入大小前缀......整个事情看起来很奇怪)。您用来组装和链接的实际命令是什么?你如何在这两种情况下转储结果? -
@davmac 链接器没有这样做。是 NASM。他需要一个
BITS 16指令来明确说明。 -
@RossRidge 好的,但他的 cmets 中“nasm”列中的操作码看起来像正确的 16 位代码。当然,我不知道他实际上是从哪里得到的。
-
@davmac NASM 根据使用的对象格式为 BITS 选择默认值。
elf默认为 32,bin默认为 16。 -
@Willdorf 您可以使用 32 位指令,但代码必须在 16 位模式下生成。 (将根据需要生成带有操作数大小前缀的 32 位指令)。您现在看到的是不应该出现的操作数大小前缀 (66h)。 (处理器可以处于 16 位或 32 位模式;在任何一种模式下,66h 前缀都会切换到备用操作数大小。引导扇区将以 16 位模式执行)。
标签: assembly x86 nasm bootloader osdev