访问此字符串常量的程序集有什么问题?

时间:2011-05-06 15:59:55

标签: assembly nasm

我以为我开始明白最新情况,但我现在花了很多年才试图理解为什么以下不起作用:

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 我认为0x84000x7c00 + 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

4 个答案:

答案 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”的第一个字节而不是它的地址。