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



请帮助我理解问题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

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中的指针会随着时间的推移而变化,使该例程成为程序中灵活的一部分。

最新更新