Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 此程序集访问此字符串常量有什么问题?_Assembly_Nasm - Fatal编程技术网

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

Assembly 此程序集访问此字符串常量有什么问题?,assembly,nasm,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运行它时,我发现end指令实际上

我原以为我开始明白发生了什么,但我现在花了很长时间试图理解为什么以下方法不起作用:

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运行它时,我发现end指令实际上如下所示:

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从输出开始的偏移量-当我发现使用Org0时,使用的地址是0x0800时,我注意到了这一点

我仍然不明白到底发生了什么——发现这一点让我更加困惑

根据要求,使用NDISAM进行拆卸:


嗯……”H’是0x48。可能您正在提取“Hello World”的第一个字节,而不是它的地址。

除非您使用bin格式,否则允许nasm将数据移动到段中。数据这在编译为PE格式(如.EXE)时非常有意义

换句话说,您确定输出二进制文件布局和链接后0x8400不是正确的地址吗?我知道您试图在segment.text中发出数据-为此,我认为您需要bin指令

编辑:

鉴于您使用的是bin格式,并且考虑到在segment.data中构建HelloWorld字符串确实有效的其他信息,我怀疑您需要做的是:

lea si, [cs:HelloWorld]
我可能对语法不感兴趣——我用16位x86编码已经好几年了——但问题是,你得到的偏移量是基于对ds值的假设,你正在明确地清除它,汇编程序可能会假设它的值是segment.code或类似的值。感谢Aaron将我的mov修改为lea。

来自帮助:

包含代码的第一个对象文件 应该以 像RESB 100h这样的线。这是为了 确保代码从偏移量开始 相对于试验开始的100小时 代码段,以便链接器或 转换器程序不必 在中调整地址引用 在生成.COM文件时使用。 其他汇编程序使用ORG指令 为此,NASM中的ORG是一个 格式特定于bin的指令 输出格式,并不意味着 和它在美国的情况一样 MASM兼容汇编程序

所以,代码段CS和数据段DS不相等,因此标签指针也不同,取决于节。
在x86下,节对齐通常是4096字节,适合内存页的大小。

升级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
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
使用nasm 2.09.08,我得到了以下预期拆卸:

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
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

我想这是一个发布候选是有原因的…:

什么会将半字节反转为0x84?我也在想-除非值是0x4800,而不是0x8400。还有-这是一个16位的移动。我想知道这一点,所以尝试更改字符串以另一个字符开头,但我得到了相同的值,所以得出结论这只是巧合。哦,对了。这就是为什么我很久以前就退出了汇编语言,开始让我感到阅读困难。你是如何构建和运行它的?下面是我看到的:mov si,07c08您是否在nasm命令行上使用任何特殊标志?当我通过nasm运行上述代码时,我得到了您所期望的结果。是的,请给我们完整的nasm命令行,以复制此命令。@Aaron我使用的是nasm input.asm-f bin-o output.bin。@Trefor-No。汇编程序肯定会将字符串放在mov指令之后。这就是汇编程序的工作方式-它们不会将内容从您键入的位置移开。因此,我使用-f bin,并且0x7C08是调试时字符串的实际地址。我相信语法是mov-si,[cs:HelloWorld],但NASM只生成mov-si,[ds:0x8400],我仍然不明白。@Kragen-我相信最后一句话将地址[cs:HelloWorld]处的数据移动到si-而不是地址。要移动它的地址,您需要lea-si[cs:HelloWorld]。但我也不相信这是你想要的。但它们不是被0x100关闭的,而是被0x800关闭的-这是一个4096字节的VM页面,让我想知道他的@data是否等于他的@text减去0x800-为EXE上的PE或MZ头留出了空间。不,不要手动初始化DS和SC SS段寄存器,这是在程序启动前完成的。正确的CS和DS值写入程序头表中。CS和DS之间的内存空间在com上定义
正常情况下,至少要在一个内存页上堆积时间。因此,您必须使用.text、.data和.bsst节。这是一个引导加载程序,因此没有程序头表。再次感谢您的帮助-我现在觉得这两者都有点聪明,因为我意识到我的程序集一直都是正确的,而且对于安装错误的版本来说真的很愚蠢!