使用$符号将值赋给上一行中存在的变量 [英] Assigning value to the variable present in previous line using $ sign
问题描述
我试图理解MS-DOS v2.0 源代码,并且特别是 MSDATA.ASM中的某些代码.该代码最初是使用35年以上的MASM汇编程序(该版本尚未在市场上出售)进行汇编的.我感兴趣的代码即将开始:
I'm trying to understand the MS-DOS v2.0 source code, and in particular some of the code in MSDATA.ASM. This code was originally assembled with a 35+ year old MASM assembler (a version that wasn't commercially available). The code I'm interested in is near the beginning:
SUBTTL Initialized data and data used at DOS initialization
PAGE
; DATA AREA for MS-DOS
IFNDEF KANJI
KANJI EQU 0 ;FALSE
ENDIF
CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
EXTRN international_table:BYTE
EXTRN Current_Country:WORD
ORG 0
CONSTRT EQU $ ; Start of constants segment
PUBLIC DevStrLen
DEVSTRLEN DB 3 ; Size of below
PUBLIC DevString
DEVSTRING DB "DEV" ; Dummy device directory
;
; Table of routines for assignable devices
;
; MSDOS allows assignment if the following standard devices:
; stdin (usually CON input)
; stdout (usually CON output)
; auxin (usually AUX input)
; auxout (usually AUX output)
; stdlpt (usually PRN output)
;
; SPECIAL NOTE:
; Status of a file is a strange idea. We choose to handle it in this manner:
; If we're not at end-of-file, then we always say that we have a character.
; Otherwise, we return ^Z as the character and set the ZERO flag. In this
; manner we can support program written under the old DOS (they use ^Z as EOF
; on devices) and programs written under the new DOS (they use the ZERO flag
; as EOF).
; Default FCBs for boot up
sftabl LABEL DWORD ; file table
DW -1
DW -1
DW sf_default_number ; Number of entries in table
DB sf_default_number DUP ( (SIZE sf_entry) DUP (0))
I_AM NoSetDir,BYTE ; true -> do not set directory
I_am DidCTRLC,BYTE ; true -> we did a ^C exit
I_am SpaceFlag,BYTE ; true -> embedded spaces are allowed
; in FCB
; the next two variables relate to the position of the logical stdout/stdin
; cursor. They are only meaningful when stdin/stdout are assigned to the
; console.
i_am CARPOS,BYTE ; cursor position in stdin
i_am STARTPOS,BYTE ; position of cursor at beginning
; of buffered input call
I_AM PFLAG,BYTE
I_AM VERFLG,BYTE ; Initialize with verify off
I_AM CONTPOS,WORD
PUBLIC CHARCO
CHARCO DB 00000011B ; Allows statchks every 4 chars...
I_AM DMAADD,DWORD ; User's disk transfer address
; (disp/seg)
ORG $-CONSTRT-4
DW 80H
DW ?
ENDMEM DW ?
我正试图特别理解以下代码:
I'm trying to understand this code in particular:
I_AM DMAADD,DWORD ; User's disk transfer address
; (disp/seg)
ORG $-CONSTRT-4
DW 80H
DW ?
ENDMEM DW ?
似乎定义了DWORD公共变量DMAADD
,然后将变量80H
的值80H
分配给第一个单词,然后将?
分配给第二个单词.我心中有一个疑问,也许最重要的问题是-为什么这样做,而不是将80H
的值分配给变量DMAADD
的下一行.为什么在此应用此策略,其目的是什么?为什么ORG $-CONSTRT-4
?
It appears to define a DWORD public variable DMAADD
then it assigns the variable DMAADD
the values 80H
to the first word and then ?
to the second word. I have some doubt in my mind and perhaps the most important question is - why is it doing it this way, instead of just assigning value of 80H
to the variable DMAADD
to the next line. Why is this strategy being applied here, and what is its purpose? WHy the ORG $-CONSTRT-4
?
I_AM
宏的定义和描述方式如下:
The I_AM
macro is defined and described this way:
;
; define a data item to be public and of an appropriate size/type
;
I_AM MACRO name,size
PUBLIC name
IFIDN <size>,<WORD>
name DW ?
ELSE
IFIDN <size>,<DWORD>
name DD ?
ELSE
IFIDN <size>,<BYTE>
name DB ?
ELSE
name DB size DUP (?)
ENDIF
ENDIF
ENDIF
ENDM
推荐答案
开发人员似乎打算使用I_AM
宏来使其他模块可公开访问的符号(指向BYTE,WORD和DWORD) .问题是I_AM
宏不允许您指定数据,它使数据未初始化为?
.为了解决这个问题,开发人员决定备份程序计数器以覆盖未初始化的数据,以便他们可以用80h的WORD值和未初始化的第二个WORD(?
)填充它.
It appears that the developers were intent on using the I_AM
macro to make symbols (that point at BYTEs, WORDs, and DWORDs) publicly accessible by other modules. The problem is that the I_AM
macro doesn't allow you to specify the data, it leaves it uninitialised as ?
. To get around that the developers decided to back the program counter up to overwrite the uninitialised data so they could fill it in with a WORD value of 80h and a second WORD that is uninitialised (?
).
不允许使用带有org
的负数的表达式.您无法通过以下方式备份程序计数器:
You aren't allowed to use an expressions with an org
that is negative. You couldn't back the program counter up with:
org -4
您需要一个绝对值.您需要知道程序计数器距段的开头有多远.他们选择通过在顶部设置CONSTRT
来做到这一点:
You need an absolute value. You need to know how far the program counter is from the beginning of the segment. They chose to do that by setting up CONSTRT
at the top with:
CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
EXTRN international_table:BYTE
EXTRN Current_Country:WORD
ORG 0
CONSTRT EQU $ ; Start of constants segment
在这种情况下,CONSTRT
被赋予值0(段的开始). $
是相对于段开头的当前程序计数器.
In this case CONSTRT
is given the value 0 (the start of the segment). $
is the current program counter relative to the beginning of the segment.
要确定当前程序计数器的绝对值早4个字节,可以采用当前程序计数器$
,并从段开头(设置为CONSTRT
)的程序计数器中减去它.一旦知道离分段的起点有多远,就减去4.
To determine the absolute value of the current program counter 4 bytes earlier you can take the current program counter $
and subtract it from the program counter at the beginning of the segment (which CONSTRT
is set to). Once you know how far you are from the beginning of the segment you subtract 4.
那么我们就是:
I_AM DMAADD,DWORD ; User's disk transfer address
; (disp/seg)
这定义了一个公共可访问的标签,该标签被定义为指向未初始化的DWORD值.这样会将程序计数器备份4,以替换未初始化的DWORD:
That defines a publicly accessible label that is defined as pointing at an uninitialised DWORD value. This backs up the program counter by 4 to replace the uninitialised DWORD:
ORG $-CONSTRT-4
然后发出WORD值80h,其后是未初始化的WORD值:
This then emits the WORD value 80h followed by an uninitialised WORD value:
DW 80H
DW ?
您可能已经替换了I_AM
宏,备份了指针并将数据替换为:
You could have replaced the I_AM
macro, the backing up of the pointer and replacing of the data with:
public DMAADD
DMAADD dd 80h
作为Microsoft的编码要求,DOS开发人员可能总是通过I_AM
宏导出指向BYTE,WORD,DWORD数据的标签.这完全是推测.他们可能认为通用的宏将允许他们更改导出此类数据的方法,而无需在无数地方更改代码.
It may be that the DOS developers always exported labels that point at BYTE, WORD, DWORD data via the I_AM
macro as a coding requirement at Microsoft. This is entirely speculative. They may have felt that a common macro would allow them to change the method of exporting such data without changing code in countless places.
这篇关于使用$符号将值赋给上一行中存在的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!