Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.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 理解MASM汇编程序生成的可执行代码_Assembly_X86_Dos_Masm_Coff - Fatal编程技术网

Assembly 理解MASM汇编程序生成的可执行代码

Assembly 理解MASM汇编程序生成的可执行代码,assembly,x86,dos,masm,coff,Assembly,X86,Dos,Masm,Coff,我一直在努力理解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

我一直在努力理解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
我用
masmq1.ASM
在dosbox上运行它,它生成了
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       ..............
$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       ..............
然后我运行
$linkq1.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给出的空格,它们的具体用途以及
    00000200:
    行中“L”的意义是什么


您不能期望从查看二进制输出中获得太多好处-它是由CPU(和操作系统)理解的,而不是由程序员理解的


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

广告问题1:我最喜欢的16位工具是和Borland

广告问题2:文件偏移量0x0000020E处的L字符列是一部分 机器指令的
mov-ah,4ch
。别费心了

程序的链接映像从文件偏移量0x00000200开始,以
.code
段开头,在文件偏移量0x0000021处紧跟一个对齐字节0x00,在文件偏移量0x0000022处紧跟
.data

链接器假定可执行映像将加载在线性地址0处,这永远不会发生,这就是存在重定位的原因。 MZ重定位表从文件偏移量0x1E开始,只有一个dword成员01000000,应将其解释为指向图像的16:16远指针。在本例中,它指向0000:0001,它表示文件偏移量0x00000201处的一个字,并且恰好具有值0x0001。它是机器指令的imm字段
mov ax,@data
,组装为
b80100

DOS加载器在段落地址(例如0x4C00)为可执行文件分配内存。必须将该值添加到重新定位的字中,因此指令
mov ax,@data
实际上将组装为
b8014c
,正如我们在调试器中看到的那样。

您可以使用
objdump
或等效工具。
L
0x4c
它是
mov-ah,4ch
@Jester的机器代码的一部分。为什么它写在打印到stdout的实际对象之前,在这种情况下是
hello
。我的意思是退出程序应该在打印后,对吗?数据不会被执行,它可以在二进制文件中的任何地方。请注意,在您的问题中没有反汇编(返回到机器代码的可读文本表示),只有二进制文件的十六进制转储。我也会标记(文件格式为.exe),但只允许5个标记。我留下了反汇编标签,以防将来的读者在查看hexdumps时会有与您相同的误解,并在此基础上进行搜索。我会下载Openwatcom。我们有一个WDUMP程序,它有一个
-i
选项,可以显示所有的头信息,并以良好的可读格式列出DOS EXE程序的所有重新定位项。谢谢,但我真的希望我能以某种方式理解这些重新定位是如何发生的,或者修改记录是如何编写的。我不确定,但我认为(而且看起来)您的简单程序不需要任何重新定位。当存在大数据段或多个代码段时,可能需要重新定位,而这些数据段或代码段在简单的测试程序中都无法得到。@同步器:不,我不正确。根据(抱歉,仅在德语中找到)偏移量0x06给出了重定位表中的条目数,其实际偏移量为0x18(此处为0x1e)。所以值是0x0001,0x0001,但这意味着什么,我不知道。