gpt4 book ai didi

assembly - NASM 引导加载程序中的 jmp $

转载 作者:行者123 更新时间:2023-12-03 09:17:54 27 4
gpt4 key购买 nike

我试图从 Bootloader 编写引导加载程序。编写的代码是

BITS 16

start:
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096

mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax


mov si, text_string ; Put string position into SI
call print_string ; Call our string-printing routine

jmp $ ; Jump here - infinite loop!


text_string db 'This is my cool new OS!', 0


print_string: ; Routine: output string in SI to screen
mov ah, 0Eh ; int 10h 'print char' function

.repeat:
lodsb ; Get character from string
cmp al, 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat

.done:
ret


times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature

我不明白的是我们为什么要写jmp$。通过写入jmp$,它进入无限循环。所以,进入无限循环后,最后两行

times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
dw 0xAA55 ; The standard PC boot signature

永远不会被执行。

此外,为什么我们要在 ax 中添加 288?

最佳答案

$是当前指令的地址,所以 jmp $正在循环自身。这通常是针对 fatal error 而执行的。

这里,加载器不完整,所以它输出一条消息然后循环。 “循环”指令[希望]将被[待添加]的真实代码取代。

db 定义的事物或dw伪操作是数据的定义,并且不是可执行指令[通常——除非您需要汇编器未知的特殊指令]。

因此,如果没有无限循环,您将尝试执行text_string:处的数据。 ,这会产生未定义/意外的结果,更不用说尝试执行引导 block 的最后部分了。


288偏移...

启动加载地址为0x07C00 。它正在尝试在位置 (0x07C00 + 4096 + 512) 设置其堆栈段。 --> 0x8E00 。但是,它试图将其放入段寄存器中,因此该值必须右移 4 位。 0x07C0 已经转移并且 288(4096 + 512) >> 40x0120SS 的最终值是 0x07C0 + 0x0120 --> 0x08E0 [地址0x8E00 ]

这似乎是错误的(即算术不匹配),但是sp寄存器设置为4096 ,所以 ss:sp 的最后安息之地地址是0x9E00 .

在8086实模式寻址中,所有地址都使用段寄存器和一些偏移量。最终地址为:address = (segreg << 4) + offset 。这是由硬件在以某种方式访问​​内存的每条指令上完成的。

当您在代码中跳转时,您可以使用 CS [代码段]寄存器。数据访问使用DS [数据段]寄存器。和堆栈访问(例如push/pop%sp相对,使用SS[堆栈段]寄存器。还有一个在字符串指令中使用的ES[额外段]寄存器。

关于assembly - NASM 引导加载程序中的 jmp $,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35762970/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com