2015-04-01 61 views
0

我有一個加載自身住宅的程序,以及在COM實現一切正常,但是當我試圖給我的程序轉換我面臨的問題。問題是,程序關閉,無負載住宅,它是由這一行造成的:轉換COM到EXE

call OLD_INT_PROC 

其中OLD_INT_PROC是一個雙字值,節省了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

調用OLD_INT_PROC因爲它通過IRET退出,和自己的處理程序也與IRET離開第一可能是一個問題。你可以讓你的代碼先運行,然後恢復所有的寄存器,並跳到OLD_INT_PROC。

而且,我不知道如何使用與.EXE一個終止並保持駐留程序,其中包括一個數據段,代碼段和堆棧段,對一個.COM這僅僅是一個單段。

+0

有一件事,爲什麼這段代碼在.COM程序中起作用?以及爲什麼在.EXE中設置新的1Ch中斷後,我的處理程序工作正常,沒有問題的代碼行,但似乎我沒有恢復DS段寄存器,因爲時鐘顯示,但有一些gurbage。 – GALIAF95 2015-04-02 09:03:07

+0

使用.COM程序時,所有段通常都設置爲相同的值,即cs == ds == es == ss。使用.EXE,您可以將數據和堆棧分組爲相同的段,但通常cs不會等於ds或ss。彙編器將生成一個常量,您可以使用它來加載ds或ss,因此可以設置段寄存器。終止和駐留常駐呼叫使用cs和dx,因此您可能需要根據exe的實際結尾與cs的相對位置來調整dx。 – rcgldr 2015-04-02 09:50:12

+0

好吧,我想我明白了。但還有另一個問題。如何爲.EXE釋放內存,用於.COM我使用了int21h的49h。但我怎麼能爲.EXE做同樣的事情。我的.EXE的結構像STACK SEG-CODE SEG,當我嘗試釋放未使用的內存時,我將PSP地址移到ES並使用49h,但沒有任何反應。或者我需要使用49h與我的所有細分:STACK SEG和CODE SEG? – GALIAF95 2015-04-03 07:50:57