为什么我的机器代码没有按预期运行?
Why does my machine code not behave as expected?
我正在使用 DOSBox 调试器作为环境来探索基于 x86/64 的处理器如何遍历机器代码。
作为参考,我使用的 "DOS2 length-delimited output" 示例位于:
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
这有点类似于 link 中的代码(当然我也尝试过),它确实按预期打印了一个长度为 6 的字符串。
但是,字符串不是从我想要的位置获取的,因此输出只是一堆字符,而不是十六进制代码中存在的 "Hello!"。
对正在发生的事情有什么想法吗?
我按照 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!"
我正在使用 DOSBox 调试器作为环境来探索基于 x86/64 的处理器如何遍历机器代码。
作为参考,我使用的 "DOS2 length-delimited output" 示例位于: 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
这有点类似于 link 中的代码(当然我也尝试过),它确实按预期打印了一个长度为 6 的字符串。
但是,字符串不是从我想要的位置获取的,因此输出只是一堆字符,而不是十六进制代码中存在的 "Hello!"。
对正在发生的事情有什么想法吗?
我按照 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!"