在 NASM 中创建常量时出现奇怪的内存布局
考虑以下部分引导加载程序的汇编代码:
bits 16
org 0x7C00
msg_init db 'Initializing...', 0Ah, 0Dh, 0
msg_completed db 'Completed', 0Ah, 0Dh, 0
jmp start
start:
xor ax, ax
mov ds, ax
mov es, ax
mov si, msg_init
call print
mov si, msg_completed
call print
mov al, '*'
mov bx, 0
mov ah, 0Eh
int 10h
cli
hlt
print:
lodsb ; al = [ds:si] - char to write
or al, al ; set zero flag if al=0
jz return ; jump to return if zero flag set
mov bx, 0 ; bh = page #, bl = color
mov ah, 0Eh ; function = teletype output
int 10h ; video interrupt
jmp print ; print next char if not zero
return:
ret ; return
times 510-($-$$) db 0
dw 0xAA55
内存布局如下所示:
0000: 49 6e 69 74 69 61 6c 69-7a 69 6e 67 2e 2e 2e 0a Initializing....
0010: 0d 00 43 6f 6d 70 6c 65-74 65 64 0a 0d 00 e9 00 ..Completed.....
0020: 00 31 c0 8e d8 8e c0 be-00 7c e8 11 00 be 12 7c .1.......|.....|
0030: e8 0b 00 b0 2a bb 00 00-b4 0e cd 10 fa f4 ac 08 ....*...........
0040: c0 74 09 bb 00 00 b4 0e-cd 10 eb f2 c3 00 00 00 .t..............
当我将 msg_completed
常量更改为“Enabled”时,即 msg_completed db 'Enabled', 0Ah, 0Dh, 0
内存布局更改为:
0000: 00 f0 e3 fe 00 00 2e 0a-00 00 15 7c 00 00 57 2a ...........|..W*
0010: 0d 00 45 6e 61 62 6c 65-64 0a 0d 00 e9 00 00 31 ..Enabled......1
0020: c0 8e d8 8e c0 be 00 7c-e8 11 00 be 12 7c e8 0b .......|.....|..
0030: 00 b0 2a bb 00 00 b4 0e-cd 10 fa f4 ac 08 c0 74 ..*............t
0040: 09 bb 00 00 b4 0e cd 10-eb f2 c3 00 00 00 00 00 ................
似乎前几个字节被覆盖。有什么想法吗?
Consider the following assembler code for a partial boot loader:
bits 16
org 0x7C00
msg_init db 'Initializing...', 0Ah, 0Dh, 0
msg_completed db 'Completed', 0Ah, 0Dh, 0
jmp start
start:
xor ax, ax
mov ds, ax
mov es, ax
mov si, msg_init
call print
mov si, msg_completed
call print
mov al, '*'
mov bx, 0
mov ah, 0Eh
int 10h
cli
hlt
print:
lodsb ; al = [ds:si] - char to write
or al, al ; set zero flag if al=0
jz return ; jump to return if zero flag set
mov bx, 0 ; bh = page #, bl = color
mov ah, 0Eh ; function = teletype output
int 10h ; video interrupt
jmp print ; print next char if not zero
return:
ret ; return
times 510-($-$) db 0
dw 0xAA55
The memory layout looks like this:
0000: 49 6e 69 74 69 61 6c 69-7a 69 6e 67 2e 2e 2e 0a Initializing....
0010: 0d 00 43 6f 6d 70 6c 65-74 65 64 0a 0d 00 e9 00 ..Completed.....
0020: 00 31 c0 8e d8 8e c0 be-00 7c e8 11 00 be 12 7c .1.......|.....|
0030: e8 0b 00 b0 2a bb 00 00-b4 0e cd 10 fa f4 ac 08 ....*...........
0040: c0 74 09 bb 00 00 b4 0e-cd 10 eb f2 c3 00 00 00 .t..............
When I change the msg_completed
constant to "Enabled" i.e. msg_completed db 'Enabled', 0Ah, 0Dh, 0
the memory layout changes to:
0000: 00 f0 e3 fe 00 00 2e 0a-00 00 15 7c 00 00 57 2a ...........|..W*
0010: 0d 00 45 6e 61 62 6c 65-64 0a 0d 00 e9 00 00 31 ..Enabled......1
0020: c0 8e d8 8e c0 be 00 7c-e8 11 00 be 12 7c e8 0b .......|.....|..
0030: 00 b0 2a bb 00 00 b4 0e-cd 10 fa f4 ac 08 c0 74 ..*............t
0040: 09 bb 00 00 b4 0e cd 10-eb f2 c3 00 00 00 00 00 ................
It seems the first few bytes are overwritten. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我没有观察到这种行为(在 Windows XP 上尝试过“2003 年 6 月 13 日编译的版本 0.98.36”和“2011 年 7 月 15 日编译的版本 2.09.10”)。所有 4 个二进制文件中都存在“初始化”。
你确定你没有改变任何其他东西吗?第二种情况下的二进制文件是 NASM 输出的内容,而不是您从媒体读回的内容?
顺便说一句,你的代码不会工作。 CPU将从头开始执行引导扇区,即从
db 'Initializing...', 0Ah, 0Dh, 0
开始执行。那是数据,而不是代码。此外,最好确保
CS=0
和IP>=0x7C00
位于代码早期(某些 BIOS 跳转到0x7C0:0
code> 而不是0:0x7C00
),并在LODSB
之前使用CLD
清除FLAGS.DF
。I don't observe such behavior (tried "version 0.98.36 compiled on Jun 13 2003" and "version 2.09.10 compiled on Jul 15 2011" on Windows XP). "Initializing" is there in all 4 binaries.
Are you sure you didn't change anything else? And the binary in the second case is what NASM output, not what you read back from media?
Btw, your code isn't going to work. The CPU will start executing the boot sector from its very beginning, from
db 'Initializing...', 0Ah, 0Dh, 0
. That's data, not code.Also, it would be a good thing to ensure that
CS=0
andIP>=0x7C00
early in the code (some BIOSes jump to0x7C0:0
instead of0:0x7C00
) and clearFLAGS.DF
withCLD
prior toLODSB
.