将COM转换为EXE

时间:2015-04-01 21:35:27

标签: assembly masm

我有一个程序将自己加载为住宅,并在COM实现一切正常,但当我试图转换我的程序时,我遇到了问题。问题是程序在没有作为住宅加载的情况下关闭,这是由这条线引起的:

   call OLD_INT_PROC

其中OLD_INT_PROC是双字值,用于保存标准1Ch中断的CS和IP(来自定时器)。因此,我认为这行代码称为标准中断,因此我可以安全地使用我的DS。接下来的两个程序:首先是新的中断程序(显示控制台窗口左上角的时间),第二个是设置中断程序:

  NEW_TIMER_INT_PROC proc far
    pushf
    call OLD_INT_PROC 
    push DS
    push ES
    push AX
    push BX
    push CX
    push DX
    push DI

    mov AH, 2       ;Get current time 
    int 1Ah         ;CH - hours, CL - minutes, DH - seconds

    xor BX, BX
    mov AL, CH
    call BUF_FILL
    mov AL, CL
    call BUF_FILL
    mov AL, DH
    call BUF_FILL

            mov     ax,  0B800h             
            mov     es,  ax                 
            xor     di,  di                 
            xor     bx,  bx                 
            mov     ah,  1Bh                
    @@1:    mov    al,  BUF[bx]
            stosw              
            inc     bx         
            cmp     BUF[bx],  0
            jnz     @@1        

    @@5:                       
    ;mov DX, offset BUF
    ;call PRNT_MARKED_STRING
    pop DI
    pop DX
    pop CX
    pop BX
    pop AX
    pop ES
    pop DS
    popf
    mov AL, 20h
    out 20h, AL
    iret
NEW_TIMER_INT_PROC endp

LOAD_RESIDENT proc near
    mov IS_RESIDENTAL_STR, 'Y'              ;Defines special data for residental programm
    mov IS_RESIDENTAL_STR + 1, 'e'
    mov IS_RESIDENTAL_STR + 2, 'a'
    mov IS_RESIDENTAL_STR + 3, 'h'

    push ES
    mov AX, 351Ch                       ;Installing new interruption on 1Ch
    int 21h
    mov word ptr OLD_INT_PROC, BX
    mov word ptr OLD_INT_PROC + 2, ES
    pop ES

    push DS 
    mov DX, offset NEW_TIMER_INT_PROC
    mov AX, seg NEW_TIMER_INT_PROC
    mov DS, AX
    mov AX, 251Ch
    int 21h
    ;after i run this line in MASM program closes itself
    ;but if i comment problem line discribed above
    ;program loads ok, but my newly installed interruption
    ;doesnt work with my DS
    ;it loads time somewhere else, i'm considering it loads time in 
    ;DS = ES of standard interruption
    pop DS 

    mov AX, 3100h
    ;mov BX, ES
    mov DX, offset NEW_TIMER_INT_END_MARK
    ;sub DX, BX
    mov CL, 4
    shr DX, CL
    int 21h
LOAD_RESIDENT endp

我和MASM一起工作,因为老师这么说。 :)

1 个答案:

答案 0 :(得分:1)

首先调用OLD_INT_PROC可能是一个问题,因为它通过iret退出,并且你自己的处理程序也会退出iret。您可以先运行代码,然后恢复所有寄存器并远程跳转到OLD_INT_PROC。

另外,我不确定使用.EXE终止和驻留程序,包括数据段,代码段和堆栈段,而.COM只是一个段。