【问题标题】:nasm bootloader, why does where i define ths string matter?nasm bootloader,为什么我在哪里定义字符串很重要?
【发布时间】:2015-01-18 15:15:12
【问题描述】:

我正在尝试用 nasm 编写引导加载程序,目前它只打印一个字符串。

[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 中运行它。

【问题讨论】:

  • 想想我刚刚想通了,处理器可能认为字符串是代码,执行它并将事情搞砸了。如果我将字符串定义移过永无止境的循环,一切都很好

标签: nasm bootloader


【解决方案1】:

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

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

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

这是一个更正的版本,提前声明了数据:

[BITS 16]
[ORG 0]

;;; Set CS and DS
jmp 0x07c0: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

实际上,这会在您的代码之前执行。很幸运,这个片段不会阻止您的代码工作。

【讨论】:

    猜你喜欢
    • 2019-02-20
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多