我正在使用DOSBox调试器作为探索基于x86 / 64的处理器如何遍历机器代码的环境。
作为参考,我使用的是“ DOS2长度分隔的输出”示例,该示例位于: https://montcs.bloomu.edu/~bobmon/Information/LowLevel/Assembly/hello-asm.html
我尝试了几种不同的方法,但是产生的结果最接近我想要的结果。
我正在使用十六进制编辑器手动输入字节,这是我当前保存在名为“ executable.com”的文件中的十六进制代码:
68 DD 01 1F B2 00 B6 00 B1 06 B3 01 B4 40 B0 00
CD 21 B4 4C B0 00 CD 21 48 65 6C 6C 6F 21 0A D0
0A 24 20
通过调试器执行此文件将给出以下代码概述:
01DD:0100 68DD01 push 01DD
01DD:0103 1F pop ds
01DD:0104 B200 mov dl,00
01DD:0106 B600 mov dh,00
01DD:0108 B106 mov cl,06
01DD:010A B301 mov bl,01
01DD:010C B440 mov ah,40
01DD:010E B000 mov al,00
01DD:0110 CD21 int 21
01DD:0112 B44C mov ah,4C
01DD:0114 B000 mov al,00
01DD:0116 CD21 int 21
这有点类似于链接中的代码(我当然也尝试过),并且确实输出了长度为6的字符串。
但是,字符串不是从我想要的位置获取的,因此输出只是一堆字符,而不是“ Hello!”。十六进制代码中显示的内容。
有什么想法吗?
答案 0 :(得分:2)
我按照彼得·科德斯(Peter Cordes)的建议使用NASM重新创建了示例,该示例最初产生的结果与我以前的尝试完全相同,但是当我在汇编源的开头添加“ org 0x100”时,得到的结果是我一直在寻找的
从本质上讲,这会将偏移量添加到所有地址,因为代码被加载到地址0x100而不是0x00的内存中。 在此示例中,“ org 0x100”仅导致产生的结果发生一位更改,但这一位是在正确位置从内存读取与尽早读取256个字节之间的差异。
这是最终机器代码的结果:
BA 13 01 B9 06 00 BB 01 00 B8 00 40 CD 21 B8 00
4C CD 21 48 65 6C 6C 6F 21
以及用于生成它的汇编代码:
org 0x100
mov dx, msg
mov cx, 0x06
mov bx, 1
mov ax, 0x4000
int 0x21
mov ax, 0x4C00
int 0x21
msg db "Hello!"