ROM_CALL如何在8086汇编语言编程中工作?

时间:2018-12-27 07:57:13

标签: assembly x86-16

请帮助我理解问题1和2。

标记为“问题1”的代码行如何工作?
当我们在“问题2”中调用 ROM_CALL 时会发生什么?

ROMRTN  DD      0FE000000H      ;Main ROM entry point.

ROM_CALL:
    PUSH    DI
    PUSH    SI
    PUSH    BP
    PUSH    DX
    PUSH    ES
    CALL    CS:DWORD PTR [ROMRTN]     ;PROBLEM 1
    POP     ES
    POP     DX
    POP     BP
    POP     SI
    POP     DI
    RET

    PAGE
    SUBTTL  Initalization code and temporary work areas.

;
; Overlayed by MSDOS by SYSINIT.
;

WRKSTK  LABEL   WORD
    DB      100 DUP (?)


HWINIT: XOR     BP,BP
    MOV     SS,BP
    MOV     SP,OFFSET WRKSTK+98     ;Some nice area for 
                                                                  ;stack

    PUSH    CS
    POP     ES

    MOV     BX,ROM_INIT
    CALL    ROM_CALL                           ;PROBLEM 2
    MOV     AH,0
    MOV     MCON,AX

    MOV     AX,SEG SYSINIT
    MOV     DS,AX

ASSUME  DS:SEG SYSINIT

    MOV     AX,CS
    ADD     AX,BIOSIZS
    MOV     DS:[CURRENT_DOS_LOCATION],AX
    MOV     DS:[MEMORY_SIZE],MAX_MEM
    MOV     AX,CS
    MOV     WORD PTR DS:[DEVICE_LIST+2],AX
    MOV     WORD PTR DS:[DEVICE_LIST],OFFSET 
    DEVSTART
    MOV     AX,CS
    ADD     AX,((OFFSET WRKSTK - OFFSET INIT)+50) /16
    MOV     DS:[FINAL_DOS_LOCATION],AX
    JMP     SYSINIT

DOSSPOT LABEL   WORD

CODE    ENDS

    END

我认为下面给出的URL将帮助您理解逻辑。代码捕捉来自完整程序的最后一部分。

https://github.com/Microsoft/MS-DOS/blob/master/v2.0/source/SKELIO.ASM

1 个答案:

答案 0 :(得分:2)

CALL    CS:DWORD PTR [ROMRTN]     ;PROBLEM 1
     

问题1中提到的代码行如何工作

此指令对内存位置进行了远距离调用,其地址存储在标有 ROMRTN 的变量中。

ROMRTN  DD      0FE000000H      ;Main ROM entry point.

尽管您看到的是显示为32位双字,但实际上您需要将其视为一个段:偏移对。毕竟这是16位代码!

ROMRTN  DD      0FE00h:0000h      ;Main ROM entry point.

或写成将其存储在内存中的方式(x86为小端):

ROMRTN  DW      0000h, 0FE00h     ;Main ROM entry point.

然后,远端调用转到线性地址为0FE000h的存储位置。也就是说,您将段字(这里是0FE00h)乘以16,然后加上偏移字(这里是0000h)。


CALL    ROM_CALL                           ;PROBLEM 2
     

然后,当我们在问题2处调用ROM_CALL时会发生什么。

该指令对标有 ROM_CALL 的例程进行了近距离调用。
程序员可能已经选择内联例程的代码,但是完整的程序可能执行了其中的一些系统BIOS调用,因此节省了采用这种多级方法的空间。还可以想象,存储在 ROMRTN 中的指针会随时间变化,从而使该例程成为程序的灵活部分。