1

我一直在尝试理解 MASM 汇编器生成的目标代码和 exe 文件,但有些部分对我来说仍然模糊,希望有人能真正帮助我理解。

所以我有一个非常简单的 MASM 程序

Q1.ASM

.model small
.stack 100h

.data
string db 'hello$'
.code
MAIN PROC
    mov ax, @data
    mov ds, ax
    lea dx , string
    mov ah, 9
    int 21h
    mov ah, 4ch
    int 21h
MAIN ENDP
END MAIN

我在dosbox上运行它MASM Q1.ASM并生成Q1.OBJ

$ xxd Q1.OBJ

00000000: 8008 0006 5131 2e41 534d e196 2500 0006  ....Q1.ASM..%...
00000010: 4447 524f 5550 0444 4154 4104 434f 4445  DGROUP.DATA.CODE
00000020: 0553 5441 434b 055f 4441 5441 055f 5445  .STACK._DATA._TE
00000030: 5854 8f98 0700 4811 0007 0401 fc98 0700  XT....H.........
00000040: 4806 0006 0301 0998 0700 7400 0105 0501  H.........t.....
00000050: e19a 0600 02ff 02ff 035b 8804 0000 a200  .........[......
00000060: d1a0 0a00 0200 0068 656c 6c6f 241c a015  .......hello$...
00000070: 0001 0000 b800 008e d88d 1600 00b4 09cd  ................
00000080: 21b4 4ccd 21f0 9c0b 00c8 0115 0101 c407  !.L.!...........
00000090: 1401 0297 8a07 00c1 0001 0100 00ac       ..............

然后我跑$ link Q1.OBJ然后它生成了Q1.EXE

$ xxd Q1.EXE

00000000: 4d5a 1800 0200 0100 2000 1100 ffff 0200  MZ...... .......
00000010: 0001 c58b 0000 0000 1e00 0000 0100 0100  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000200: b801 008e d88d 1602 00b4 09cd 21b4 4ccd  ............!.L.
00000210: 2100 6865 6c6c 6f24                      !.hello$

现在我有两个问题,

  • 生成的目标代码应该有修改记录和重定位位,但都是二进制的,有什么方法可以正确分析从.OBJ文件生成的修改记录。

  • 如您所见,生成的Q1.EXE文件有许多由 0000 给出的空白,它们的具体用途是什么以及行中的“L”的含义是什么00000200:

4

2 回答 2

2

您不能指望通过查看二进制输出能够获得太多收益——它旨在由 CPU(和操作系统)而不是程序员来理解。

不过,我可以回答第二个问题:exe 文件的标头由链接器填充到 512 字节(0x200 十六进制),因此实际代码从偏移量 0x200 开始。exe 标头以魔术签名“MZ”开头。下面是代码,“L”是所用机器代码指令之一的 ascii 等价物。最后一部分是数据部分,这里只包含字符串。

于 2021-01-14T13:23:06.950 回答
0

广告问题 1:我最喜欢的 16 位工具是Object Dumper ODU.EXE和 Borland Turbo Dump

广告问题2:文件偏移量0x0000020E处的字符列中的Lmov ah, 4ch是机器指令的一部分。不要打扰它。

程序的链接图像从文件偏移量 0x00000200 开始,.code段,然后是文件偏移量 0x00000211 处的一个对齐字节 0x00,然后是 .data文件偏移量 0x00000212 处的段。

链接器假定可执行映像将在线性地址 0 处加载,这永远不会发生,这就是存在重定位的原因。MZ 重定位表从文件偏移量 0x1E 开始,并且只有一个 dword 成员 01000000,它应该被解释为指向图像的 16:16 远指针。在这种情况下,它指向 0000:0001,它表示文件偏移量 0x00000201 处的一个单词,并且恰好具有值 0x0001。它是机器指令的immmov ax, @data字段,汇编为b80100. DOS 加载程序在段落地址(例如 0x4C00)处为可执行文件分配内存。该值必须添加到重定位字中,因此该指令mov ax,@data实际上将汇编为b8014c,正如我们在调试器中看到的那样。

于 2021-01-15T08:53:45.260 回答