我以为我开始明白最新情况,但我现在花了很多年才试图理解为什么以下不起作用:
org 0x7C00
mov ax,0x0000
mov ds,ax
mov si, HelloWorld
HelloWorld db 'Hello World',13,10,0
我期待的是mov si, HelloWorld
指令会将值0x7C08
放在si
中(0x7c00
+ HelloWorld
的偏移量) ,准备好像lodsb
这样的事情。
当我构建它(使用Nasm)并运行它(使用Bochs)时,我发现结束指令实际上是这样的:
mov si, 0x8400
为什么这样,价值0x8400
来自哪里?
更新:我发现在数据段中放置HelloWorld
会产生预期的输出:
section .data
HelloWorld db 'Hello World',13,10,0
为什么会这样?
仅供参考,用于构建此命令的命令为nasm -f bin input.asm -o output.bin
更新2 我认为0x8400
是0x7c00 + 0x0800
,其中8是HelloWorld
从输出开头的偏移 - 我注意到了这一点当我发现使用org 0
时,使用的地址是0x0800
。
我仍然不明白发生了什么 - 发现这让我更加困惑!
根据要求,使用ndisasm
反汇编:
00000000 B80000 mov ax,0x0
00000003 8ED8 mov ds,ax
00000005 BE0084 mov si,0x8400
00000008 48 dec ax
00000009 656C gs insb
0000000B 6C insb
0000000C 6F outsw
0000000D 20576F and [bx+0x6f],dl
00000010 726C jc 0x7e
00000012 640D0A00 fs or ax,0xa
答案 0 :(得分:2)
除非您使用bin
格式,否则允许nasm将您的数据移动到segment .data
这在编译为.EXE等PE格式时很有意义。
换句话说,一旦输出二进制文件的布局和链接,你确定0x8400
不是正确的地址吗?我知道您正试图在segment .text
中发布数据 - 为此,我认为您需要bin
指令。
编辑:
鉴于您使用的是bin
格式,并考虑到您在HelloWorld
中构建segment .data
字符串的其他信息确实有用,我怀疑您需要做的是:
lea si, [cs:HelloWorld]
我可能会关注语法 - 自从我使用16位x86进行编码已经过了好几年 - 但关键是你根据ds
的值假设获得了一个偏移量,您明确清除的内容以及汇编程序可能假定的值为segment .code
或类似值。 (感谢Aaron将我的动作改为lea。)
答案 1 :(得分:1)
来自MASM帮助:
包含代码的第一个目标文件 应该用a开始它的代码段 像RESB 100h这样的线。这是为了 确保代码从offset开始 相对于开始的100h 代码段,以便链接器或 转换器程序不必 调整内的地址引用 生成.COM文件时的文件。 其他汇编程序使用ORG指令 为此目的,但NASM中的ORG是一个 特定于格式的指令到bin 输出格式,并不代表 和它一样的事情 与MASM兼容的汇编程序。
因此,您有代码段CS和数据段DS并且它们不相等,因此标签指针也不同,取决于节。 在x86下,部分对齐通常为4096字节,符合内存页面的大小。
答案 2 :(得分:1)
升级您的nasm副本。
使用nasm 2.09rc1我得到以下(意外)反汇编:
00000000 B80000 mov ax,0x0
00000003 8ED8 mov ds,ax
00000005 BE0084 mov si,0x8400
00000008 48 dec ax
00000009 656C gs insb
0000000B 6C insb
0000000C 6F outsw
0000000D 20576F and [bx+0x6f],dl
00000010 726C jc 0x7e
00000012 640D0A00 fs or ax,0xa
使用nasm 2.09.08我得到以下(预期)反汇编:
00000000 B80000 mov ax,0x0
00000003 8ED8 mov ds,ax
00000005 BE087C mov si,0x7c08
00000008 48 dec ax
00000009 656C gs insb
0000000B 6C insb
0000000C 6F outsw
0000000D 20576F and [bx+0x6f],dl
00000010 726C jc 0x7e
00000012 640D0A00 fs or ax,0xa
我猜这是一个候选人,原因是...... :)
答案 3 :(得分:0)
嗯......'H'是0x48。也许你正在拉“Hello World”的第一个字节而不是它的地址。