⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atoms.asm

📁 这是一些例程
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	mov     es, st_seg      ; those registers
	xor     al, al          ; clear al
	mov     cx, -1          ; by using cx=-1, repnz won't stop until 
	repnz   scasb           ; it finds a match. cx will be -(length-1) 
	not     cx              ; since we use two's complement, not cx=length!
	mov     ax, cx          ; mov length into ax, and
	ret                     ; return
st_len  ENDP    

								
;----------------------------------------------------------------------------;
;****************************************************************************;
;----------------------------------------------------------------------------;
;                                                                            ;
;       BEGINNING OF SPACE TO BE USED AS DRIVER MEMORY                       ;
;       ALL CODE AFTER ATOMLIST WILL BE ERASED BY THE DRIVER'S DATA          ; 
;       OR BY OTHER LOADED DRIVERS                                           ;
;                                                                            ;
;----------------------------------------------------------------------------;
;****************************************************************************;
;----------------------------------------------------------------------------;


;----------------------------------------------------------------------------;
;                    Initialization Data and Code               
; Only needed once, so after the driver is loaded and initialized it releases
; any memory that it won't use. The device allocates memory for its own use
; starting from 'AtomList'.
;----------------------------------------------------------------------------;

AtomList        BYTE 0
Ident           BYTE '*           ATOMS Device Driver             *',lf,cr,eom
Border          BYTE '*********************************************',lf,cr,eom
scan_default    BYTE '*     Using default value of 1024 bytes     *',lf,cr,eom
scan_ignore     BYTE '* Ignoring extra parameters in command line *',lf,cr,eom
scan_minimum    BYTE '* Minimum value of 1024 bytes  will be used *',lf,cr,eom
scan_overflow   BYTE '*  Maximum value of 32K bytes will be used  *',lf,cr,eom
HexDump         BYTE '*   Beginning atoms memory: '
Hex1            BYTE '0000h : '
Hex2            BYTE '0000h   *',cr,lf
		BYTE cr,'*   Ending atoms memory:            '
Hex3            BYTE '0000h   *',cr,lf,eom

;----------------------------------------------------------------------------;
; Init
;----------------------------------------------------------------------------;
; routine called only once to initialize the driver. It shows the startup 
; message, scans the config.sys command line, and tells MS-DOS how much memory
; it needs. Note that under DOS 5.0 the request header also tells you how  
; much memory you could use.
;----------------------------------------------------------------------------;

Init    PROC NEAR USES es di    

	@ShowStr Border                 ; use dos.inc macros to start the init
	@ShowStr Ident                  ; message

	INVOKE  int2hex, cs, ADDR Hex1  ; get starting segment in Hex
	INVOKE  int2hex,MaxMem,ADDR Hex2; get starting offset in Hex
	
	les     di, [lpHeader]          ; allow us to use the request values

	ASSUME  di:PTR REQ_HEADER       ; to use the REQ_HEADER OFFSETS

	; scan the config.sys command line
	INVOKE  scan, es:[di].cmd_off, es:[di].cmd_seg 
	
	add     ax, MemEnd              ; set ax to End of Memory relative to
					; previous end of memory.
	mov     MaxMem, ax              ; store the new value in MaxMem 
	mov     es:[di].xseg,cs         ; tell MS-DOS the end of our used 
	mov     es:[di].xfer,ax         ; memory (the break address)

	ASSUME  di:NOTHING              ; di will be something else now

	INVOKE  int2hex, ax, ADDR Hex3  ; Get ending offset in Hex 
	@ShowStr HexDump                ; print the Hex Dump of Memory bounds
	
	@ShowStr Border                 ; show the end of our initial message
	
	xor     ax, ax                  ; return status OK
	ret
Init    ENDP


;----------------------------------------------------------------------------;
; scan
;----------------------------------------------------------------------------;
; scans the string passed by ms-dos on initialization for the amount of
; memory to allocate to the driver. Since we get a pointer to the string
; after the '=', first scan over the filename and white space, then for the
; ASCII number and turn it into decimal.
; the string we'll get might have some white space (or not) before the device
; name, then the device name, then either the end-of-line (and we'd use the
; default values) or some white space and the end-of-line (same thing) or
; some white space and a number maybe followed by some white space or the end
; of line. If there's something after the number, we'll output the extra
; parameters warning.
;
; returns:    AX    = number of bytes to allocate
;----------------------------------------------------------------------------;

scan    PROC NEAR USES ds si, st_off:NPBYTE, st_seg:SEGPTR
	LOCAL   result          ; result will hold the amount to allocate
	
	mov     result, 0       ; clear the result variable
				
	mov     ds, st_seg      ; lodsb uses DS:SI as the source string 
	mov     si, st_off

	.REPEAT                 ; load from the string into the accumulator
		lodsb           ; while it's white space
	.UNTIL ((al!=tab) && (al!=space))

				; scan until we find a white space or the end
				; of the line (note that we don't test the 1st 
	.REPEAT                 ; character after the spaces: it has to be a 
		lodsb           ; letter o.w. DOS wouldn't load the driver)
	.UNTIL ((al==tab) || (al==space) || (al==cr) || (al==lf))

	.IF ((al==cr) || (al==lf))      ; if we found the end of line, we'll 
		jmp     scan_d          ; use the default values. jump there.
	.ENDIF

	.REPEAT                         ; scan for the next non-white space 
		lodsb
	.UNTIL ((al!=tab) && (al!=space))
	
	.IF ((al==cr) || (al==lf))      ; if we found the end of line, we'll 
		jmp     scan_d          ; use the default values. jump there.
	.ENDIF

	.REPEAT                         ; scan for the decimal numbers: 
		.IF ((al<'0')||(al>'9')); if it's not an ascii decimal number
		jmp     scan_i          ; ignore the parameter, use defaults
		.ENDIF
		cbw                     ; set ax to 0 (by extending al to ax)
		sub     ax, '0'         ; turn ax into a number 0-9
		mov     cx, ax          ; save the number in cx for a while,
		mov     ax, result      ; because ax will be used to multiply
		mov     bx, 10t         ; 'result' by 10, to add a 'digit' to
		mul     bx              ; the previous 'result'
		jc      scan_o          ; if we had an overflow, i.e. result
					; is more than ffffh, then use max.val
					; by jumping to the overflow section.   
		add     ax, cx          ; else, add the units to the multiplied 
		mov     result, ax      ; result, and store it where it goes
		lodsb
	.UNTIL ((al==tab) || (al==space) || (al==cr) || (al==lf))
					; when we find a space, tab, cr, or lf,
					; it's not an error: we've finished
					; the number scan.

	.IF ((al==cr) || (al==lf))      ; if we found the end of line, we'll 
		jmp     scan_d          ; use the result value so far.
	.ENDIF

	.REPEAT                         ; skip over the white space, again
		lodsb                   
	.UNTIL ((al!=tab) && (al!=space))

	.IF ((al==cr) || (al==lf))      ; if we found the end of line, we're 
		jmp     scan_d          ; fine, use the result value.
	.ENDIF
					; otherwise, we scanned something not
					; a space or end-of-line after the 
					; digits, so we drop into the ignore
					; warning display.
					
scan_i: 
					; we found something extra
	@ShowStr scan_ignore,cs         ; show the warning string
					; and drop into scan_d
		
scan_d:                                 
	push    cs                      ; make local data addressable (since
	pop     ds                      ; we rewrote ds in the scanner above)
	.IF (result == 0)               ; if we didn't scan anything into
		@ShowStr scan_default   ; result, show a warning that we will
		mov     ax, BUFMINIMUM  ; use the minimum. Set ax to minimum.
	.ELSEIF (result < BUFMINIMUM)   ; if the result is less than the 
		@ShowStr scan_minimum   ; minimum, display a warning and set 
		mov     ax, BUFMINIMUM  ; the buffer to the minimum
	.ELSEIF (result > BUFMAXIMUM)   ; if result is more than the maximum
		@ShowStr scan_overflow  ; display a message to inform the user
		mov     ax, BUFMAXIMUM  ; and set the buffer to the maximum
	.ELSE                           ; otherwise, result is acceptable
		mov     ax, result      ; set ax to result.
	.ENDIF                  
	ret                             ; return

scan_o:                                 ; overflows (request for >ffffh buffer)
	mov     result, BUFMAXIMUM+1    ; set ax to a value that will cause  
	jmp     scan_d                  ; scan_d to print out an overflow 
					; message and set buffer to 32K

scan    ENDP


;----------------------------------------------------------------------------;
; int2hex 
; Converts a WORD into its hexadecimal representation. 
; Based on Chapter 4 of the MASM Programmer's guide
;----------------------------------------------------------------------------;

; Table of hexadecimal digits
hex     BYTE    '0123456789ABCDEF'

int2hex PROC NEAR USES ax bx si, number:WORD, string:NPBYTE

	mov     bx, OFFSET hex          ; load table address
	mov     si, string

	mov     ax, number              ; load value to convert 
	shr     ax, 12                  ; shift right to get into table index
	and     ax, 0000Fh              ; remove all but least-significant byte
	xlat                            ; translate
	mov     [si], al                ; store as last byte

	mov     ax, number              ; load value to convert 
	shr     ax, 8                   ; shift right to get into table index
	and     ax, 0000Fh              ; remove all but least-significant byte
	xlat                            ; translate
	mov     [si+1], al              ; store as third to last byte

	mov     ax, number              ; load value to convert 
	shr     ax, 4                   ; shift right to get into table index
	and     ax, 0000Fh              ; remove all but least-significant byte
	xlat                            ; translate
	mov     [si+2], al              ; store as second to last byte

	mov     ax, number              ; load value to convert 
	and     ax, 0000Fh              ; remove all but least-significant byte
	xlat                            ; translate
	mov     [si+3], al              ; store as last byte in string

	ret

int2hex ENDP

	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -