回 帖 发 新 帖 刷新版面

主题:请问怎样把一个EXE文件转化为COM文件呢?

我编写了一个十进制转换为十六进制的汇编代码,最终实现了自己的功能。
但现在由于需要,我必须把它转换成COM文件,该怎么办呢?

代码如下:
DATA     segment para public 'data'
msg1     DB    'Please input a number:'
         DB    '(0-65535):$'
msg2     db    'The hex result is:$'
msg3     db    'Input error!$' 
nhex     dw    ?  ;存放二进制结果
DATA     ends

sseg    segment stack
            dw 100 dup (?)
sseg    ends

CODE    SEGMENT ;代码段开始

ASSUME CS:CODE, DS:DATA,SS: sseg
main    proc far;主程序开始
start:  push ds;
        xor ax,ax;
        push ax;标准序
        MOV    AX, DATA
        MOV    DS, AX
        mov   dx,offset msg1
        mov   ah, 9
        int   21h;显示提示信息
        call   decibin;调用转换子程序
        and    al,al ;检查AL=0?
        jnz    main1;AL非0,出错
        mov   nhex,bx;存转换结果
        call    crlf;显示回车换行
        mov   dx,offset msg2
        mov   ah, 9;显示提示信息
        int     21h;
        call   binihex;调用显示程序
        jmp    main2 
main1:  call   crlf
        lea    dx,msg3;
        mov    ah,9;显示出错信息
           int    21h;
main2:  call   crlf
           ret   ;返回DOS
main   endp;主程序结束

decibin    proc    
        XOR    BX, BX
newchar: MOV    AH, 1
        INT      21H
        CMP    AL, 0DH    
        JE       DONE
        SUB    AL, 30H
        JL       err
        CMP    AL,9
        JG      err
MOV    CX, 0AH 
       CBW
         XCHG   AX, BX
       MUL    CX
       ADD    BX, AX
       JMP    newchar
err:   MOV    AL, 0ffh
       RET 
DONE:   MOV   AL,0   
        RET
decibin  ENDP

binihex proc
        mov    ch, 4
rotate:  mov    cl, 4
        rol       bx, cl
        mov    al, bl
        and    al, 0fh
        add    al, 30h
        cmp    al, 3ah
        jl         printit
        add    al, 7            
printit: mov    dl, al
        mov    ah,  2
        int      21h
        dec    ch
        jnz     rotate
        ret               
binihex  endp
crlf        proc ;回车换行子程序
  push ax 
    push dx
     mov dl,0dh 
    mov ah,2
    int 21h
  mov dl,0ah
  mov ah,2
    int 21h
  pop dx  
    pop ax
     ret
crlf        endp    

CODE ends;代码段结束
end  start;汇编结束
由于急用,所以先谢谢大家了!

回复列表 (共9个回复)

沙发

直接改扩展名就可以

也可以在DOS下用:
ren ×××.exe ×××.com

板凳

com文件和exe文件都是二进制代码,所以直接改不影响程序

3 楼

但我觉得他们对段的定义是不同的啊,
而且修改了之后他们二进制内容是一样的,
这是为什么呢?
比如,用c在TC下编写一个简单的printf函数,
最后生成的是.exe文件,这个.exe文件的执行
是要有段间调用的,所以在一个裸机下(没有
任何系统)能直接运行吗?
可能问题有点弱,但非常希望各位大虾来帮忙
说一下!
再次感谢了!·

4 楼


exe和com内部格式有差别,查一下com的信息.
规范后可用exe2bin.exe制作

5 楼

注意:
1、COM型可执行文件代码、数据、堆栈段都在一段,所以COM型文件不能长于64KB;
2、段定义不要使用简化段定义;
3、DS、ES、SS段寄存器在程序装入时就自动被装填完毕,所以没必要再进行装填;
4、程序第一条指令必须位于100h处;
5、使用Int20h软中断结束程序并返回DOS
6、符合上述格式规定之后,编译链接为EXE文件,再使用EXE2BIN转成COM文件。

示例:

CODE SEGMENT
    ASSUME CS:CODE,DS:CODE,ES:CODE
    ORG 100H
start:    JMP begin
;
;数据在这里定义
    MyData        DB    ?
    ………
    ………
;
;子程序可以紧接着放在这里,注意必须是NEAR类型
PROC1    PROC    NEAR
    ………
    ………
PROC1    ENDP
;
PROC2    PROC    NEAR
    ………
    ………
PROC2    ENDP
;
;主程序
  begin:
    ………
    ………
    INT 20h
CODE ENDS
    END start


最简单的COM(仅包含INT20h一条指令)可以使用DEBUG生成:

C:\>debug
-a
137B:0100 int 20
137B:0102
-rcx
CX 0000
:2
-n test.com
-w
Writing 00002 bytes
-q

C:\>

6 楼

没看到你后面的问题。
    EXE文件因为加载过程的再定位问题(操作系统完成),它不能在“裸机”状态下运行!但是,一旦加载定位并获取控制权以后,如果其代码没有用到DOS中断,我们可以认为它运行结束之前,是跟操作系统无关的!(这里的裸机之所以带引号,是因为我们还有BIOS中断可用。一个连BIOS中断都不使用的程序,才是类似BIOS一样直接面向硬件编程的程序)
    EXE文件可以是多数据段、多堆栈段、多代码段的,它包含一个用于再定位等信息的文件头。具体请查阅相关资料。而COM文件的数据、堆栈、代码只能在一段中,当然也由操作系统加载并定位于当前可用段偏移为100h之处,其实际最大长度应该是10000h-100h字节。
    如果没理解错,你所说的“裸机”能运行的程序,应该是类似硬盘主引导记录一样的程序。这是一段脱离任何操作系统的程序,它由BIOS中断INT19h装入内存后获取控制权。希望编制脱离OS的程序,可以研究一下它。[em2]

7 楼

确实是这样的。
有些困难,但也要坚持下去做。
毕竟做了一些部分了。

8 楼

code segment
main proc far
assume cs:code
start:
mov bx,1234
push ds
sub ax,ax
push ax
mov ch,4
rotate:
mov cl,4
rol bx,cl
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jl printit
add al,7h
printit:
mov dl,al
mov ah,2
int 21h
dec ch
jnz rotate
mov dl,'H'
mov ah,02h
int 21h
ret
main endp
code ends
end
呵呵
书上的+自己添加的点东西
似乎比LZ的简单

9 楼

呵呵,写的不错。
不过我是故意要这样来测试怎么把他转化为.com文件的,
谢谢你的热心了。

我来回复

您尚未登录,请登录后再回复。点此登录或注册