nasm bootloader,为什么我在哪里定义字符串问题?

时间:2015-01-18 15:15:12

标签: nasm bootloader

我正在尝试在nasm中编写一个bootloader,此时它只是打印一个字符串。

[BITS 16]
[org 0x7c00]

myString:
	db 'Hello World', 0x00

mov bp, 0x8000
mov sp, bp

mov bx, myString
call printString

jmp $

printString:
	pusha
	mov ah , 0x0e
	printStringA:
	
	mov al , [bx]
	cmp al, 0x00
	je printStringB
	
	int 0x10
	add bx, 0x01
	jmp printStringA
	
	printStringB:
	popa
	ret

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

工作正常,但如果我将字符串定义移动到此处:

[BITS 16]
[org 0x7c00]

mov bp, 0x8000
mov sp, bp

myString:
	db 'Hello World', 0x00

mov bx, myString
call printString

jmp $

printString:
	pusha
	mov ah , 0x0e
	printStringA:
	
	mov al , [bx]
	cmp al, 0x00
	je printStringB
	
	int 0x10
	add bx, 0x01
	jmp printStringA
	
	printStringB:
	popa
	ret

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

它打印出垃圾,我在windows下的bochs中运行它,如果这有帮助的话。

1 个答案:

答案 0 :(得分:1)

您正在组装到原始机器代码。没有数据和文本部分。一切都被解释为代码,包括使用db插入的内容。因此两个代码段都是错误的。

如果您使用无限循环(如示例中所示)或暂停指令,则可以安全地将数据放在代码之后,因为它永远不会到达。否则,您必须安排跳过数据。

您还需要在开始时正确设置段寄存器。

这是一个更正版本,早期声明数据:

[BITS 16]
[org 0x7c00]

;;; Set CS and DS
jmp 0:start

start:
mov ax, cs
mov ds, ax

;;; set SP    
mov bp, 0x8000
mov sp, bp

;;; skip over data
jmp L1

myString:
    db 'Hello World', 0x00

L1:

mov bx, myString
...

请注意,在第一个示例中,数据被解释为代码。

db 'Hello World', 0x00

组装为

48 65 6c 6c 6f 20 57 6f  72 6c 64 00

并对应于:

dec ax
gs insb
insb
outsw
and [bx+0x6f],dl
jc short 0x76
fs
db 0x00

实际上,这会在您的代码之前执行。幸运的是,这个片段并没有阻止你的代码工作。