在DOS系统下用exe2bin将.exe文件转换成.com文件
convert .exe file to .com file with exe2bin in DOS system
环境为MS-DOS系统
我有一个简单的 h.asm 代码,用于使用 dos 9# call
输出 hello world
.386
DATA SEGMENT USE16
MSG DB 'HelloWorld!$'
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET MSG
MOV AH,9
INT 21H
CODE ENDS
END BEG
使用 MASM 命令:
masm h.asm
我得到了文件 h.obj。然后 link h.obj
我得到了 h.exe 文件。
现在想通过命令获取.exe文件的.com文件
exe2bin h.exe
,但我收到的结果是:
无法转换文件
出了什么问题?
对于真实(16 位)模式汇编,根据工具集,您可以使用 TINY 模型而不是使用 exe2bin。
使用 Microsoft 16 位工具集发布版本的批处理文件:
ml /c %1.asm
link /tiny %1.obj;
用于调试 (codeview) 构建的批处理文件:
ml /Zi /c %1.asm
link /CO /tiny %1.obj;
例子MSDOS/MASM (ML.EXE) 6.11源代码:
.286
.model tiny,c
.code
org 0100h
main proc far
lea dx,msg0
mov ax,0900h ;display msg
int 21h
mov ax,04c00h ;exit
int 21h
msg0 db 'msdos tiny asm example',0dh,0ah,'$'
main endp
end main
Microsoft 16 位工具集和 16 位程序将 运行 在 32 位版本 Windows 的控制台模式下。对于 64 位版本,请使用虚拟 PC 或 DOSBOX。
程序 exe2bin
要求您要转换的 .EXE 文件具有入口点 0000:0100 或根本没有入口点。在前一种情况下,可执行文件不能有任何段重定位,结果通常是 MS-DOS 可以加载的 .COM 文件。另外.EXE文件不能有栈,加载大小必须小于或等于64K。
exe2bin
失败的直接原因是因为你有类似 0001:0000
的入口点,其中段部分是相对于可执行文件的开始并根据内存中的位置进行调整MS-DOS 加载可执行文件的位置。 (例如,如果 MS-DOS 在 1234:0000 加载可执行文件,则入口点是 1235:0000。)这不适用于 .COM 文件,因为 MS-DOS 只是将 .COM 文件复制到内存并跳转段中的偏移量 0100。 (因此,如果 MS-DOS 在 1234:0000 加载 .COM 文件,它会跳转到 1234:0100)。
您的可执行文件的另一个问题是,即使它使用了正确的入口点,它也有段重定位。 MOV AX, DATA
指令引用段 DATA
,DATA
的值取决于 MS-DOS 加载可执行文件的位置。这需要在可执行文件中进行重定位,以便 MS-DOS 在加载它时知道用正确的段值修改该值。
要制作既能与 exe2bin
一起使用又能生成可用的 .COM 文件的可执行文件,您需要以下内容:
- 程序开头的
ORG 100h
指令
- 定义入口点的符号放置在
ORG 100h
指令之后,因此它位于偏移量 100h。
- 必须将入口点符号作为参数提供给
END
指令,以便它成为入口点。
- 必须只有一个段,所有的东西都生活在其中。
- 在
ORG 100h
指令之前不能定义任何东西(否则会被exe2bin
丢弃)。
- 加载到内存中的可执行文件的大小必须小于 64K。这包括
ORG 100h
指令占用的 256 个字节。换句话说,所有内容都必须位于同一个 64K 段中。
例如,您可以像这样重写您的程序,使其变成可以生成工作 .COM 文件的程序:
.386
; Requirements implemented
CODE SEGMENT USE16 ; 4.
ORG 100h ; 1.
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE ; 4.
BEG: MOV DX,OFFSET MSG ; 2.
MOV AH,9
INT 21H
MOV AX,4C00H ; exit the program
INT 21H
MSG DB 'HelloWorld!$' ; 4. 5.
CODE ENDS
END BEG ; 3.
请注意,我添加了一个 MS-DOS 调用以退出程序,否则您的代码将在打印消息后继续执行指令。在您的原始可执行文件中,这将是随机未初始化的数据,在上面的程序中,它将是字符串 HelloWorld!$
被解释为 x86 机器代码。
正如 rcgldr 发布的那样,您可以跳过 exe2bin
步骤,让链接器使用 /TINY
选项直接生成 .COM 文件。使用此选项时,上面给出的创建 .COM 文件的规则相同。
环境为MS-DOS系统
我有一个简单的 h.asm 代码,用于使用 dos 9# call
.386
DATA SEGMENT USE16
MSG DB 'HelloWorld!$'
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET MSG
MOV AH,9
INT 21H
CODE ENDS
END BEG
使用 MASM 命令:
masm h.asm
我得到了文件 h.obj。然后 link h.obj
我得到了 h.exe 文件。
现在想通过命令获取.exe文件的.com文件
exe2bin h.exe
,但我收到的结果是:
无法转换文件
出了什么问题?
对于真实(16 位)模式汇编,根据工具集,您可以使用 TINY 模型而不是使用 exe2bin。
使用 Microsoft 16 位工具集发布版本的批处理文件:
ml /c %1.asm
link /tiny %1.obj;
用于调试 (codeview) 构建的批处理文件:
ml /Zi /c %1.asm
link /CO /tiny %1.obj;
例子MSDOS/MASM (ML.EXE) 6.11源代码:
.286
.model tiny,c
.code
org 0100h
main proc far
lea dx,msg0
mov ax,0900h ;display msg
int 21h
mov ax,04c00h ;exit
int 21h
msg0 db 'msdos tiny asm example',0dh,0ah,'$'
main endp
end main
Microsoft 16 位工具集和 16 位程序将 运行 在 32 位版本 Windows 的控制台模式下。对于 64 位版本,请使用虚拟 PC 或 DOSBOX。
程序 exe2bin
要求您要转换的 .EXE 文件具有入口点 0000:0100 或根本没有入口点。在前一种情况下,可执行文件不能有任何段重定位,结果通常是 MS-DOS 可以加载的 .COM 文件。另外.EXE文件不能有栈,加载大小必须小于或等于64K。
exe2bin
失败的直接原因是因为你有类似 0001:0000
的入口点,其中段部分是相对于可执行文件的开始并根据内存中的位置进行调整MS-DOS 加载可执行文件的位置。 (例如,如果 MS-DOS 在 1234:0000 加载可执行文件,则入口点是 1235:0000。)这不适用于 .COM 文件,因为 MS-DOS 只是将 .COM 文件复制到内存并跳转段中的偏移量 0100。 (因此,如果 MS-DOS 在 1234:0000 加载 .COM 文件,它会跳转到 1234:0100)。
您的可执行文件的另一个问题是,即使它使用了正确的入口点,它也有段重定位。 MOV AX, DATA
指令引用段 DATA
,DATA
的值取决于 MS-DOS 加载可执行文件的位置。这需要在可执行文件中进行重定位,以便 MS-DOS 在加载它时知道用正确的段值修改该值。
要制作既能与 exe2bin
一起使用又能生成可用的 .COM 文件的可执行文件,您需要以下内容:
- 程序开头的
ORG 100h
指令 - 定义入口点的符号放置在
ORG 100h
指令之后,因此它位于偏移量 100h。 - 必须将入口点符号作为参数提供给
END
指令,以便它成为入口点。 - 必须只有一个段,所有的东西都生活在其中。
- 在
ORG 100h
指令之前不能定义任何东西(否则会被exe2bin
丢弃)。 - 加载到内存中的可执行文件的大小必须小于 64K。这包括
ORG 100h
指令占用的 256 个字节。换句话说,所有内容都必须位于同一个 64K 段中。
例如,您可以像这样重写您的程序,使其变成可以生成工作 .COM 文件的程序:
.386
; Requirements implemented
CODE SEGMENT USE16 ; 4.
ORG 100h ; 1.
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE ; 4.
BEG: MOV DX,OFFSET MSG ; 2.
MOV AH,9
INT 21H
MOV AX,4C00H ; exit the program
INT 21H
MSG DB 'HelloWorld!$' ; 4. 5.
CODE ENDS
END BEG ; 3.
请注意,我添加了一个 MS-DOS 调用以退出程序,否则您的代码将在打印消息后继续执行指令。在您的原始可执行文件中,这将是随机未初始化的数据,在上面的程序中,它将是字符串 HelloWorld!$
被解释为 x86 机器代码。
正如 rcgldr 发布的那样,您可以跳过 exe2bin
步骤,让链接器使用 /TINY
选项直接生成 .COM 文件。使用此选项时,上面给出的创建 .COM 文件的规则相同。