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

📄 irvine16.asm

📁 想学习汇编语言的
💻 ASM
📖 第 1 页 / 共 2 页
字号:
TITLE  Link Library Functions		(Irvine16.asm)

Comment @

This library was created exlusively for use with the book,
"Assembly Language for Intel-Based Computers, 4th Edition",
by Kip R. Irvine, 2002.

Copyright 2002, Prentice-Hall Incorporated. No part of this file may be
reproduced, in any form or by any other means, without permission in writing
from the publisher.

Updates to this file will be posted at the book's site:
www.nuvisionmiami.com/books/asm

Acknowledgements:
------------------------------
Most of the code in this library was written by Kip Irvine.
Special thanks to Gerald Cahill for his many insights, suggestions, and bug fixes!
Also to Courtney Amor, a student at UCLA.

Alphabetical Listing of Procedures
----------------------------------
(Unless otherwise marked, all procedures are documented in Chapter 5.)

ClrScr
Crlf
Delay
DumpMem
DumpRegs
GetCommandTail
GetDateTime	Chapter 11
GetMseconds
Gotoxy
IsDigit
Random32
Randomize
RandomRange
ReadChar
ReadHex
ReadInt
ReadString
SetTextColor
Str_compare	Chapter 9
Str_copy	Chapter 9
Str_length	Chapter 9
Str_trim	Chapter 9
Str_ucase	Chapter 9
WaitMsg
WriteBin
WriteChar
WriteDec
WriteHex
WriteInt
WriteString
=================================@

INCLUDE Irvine16.inc

; Write <count< spaces to standard output

WriteSpace MACRO count
Local spaces
.data
spaces BYTE count dup(' '),0
.code
	mov  dx,OFFSET spaces
	call WriteString
ENDM

; Send a newline sequence to standard output

NewLine MACRO
Local temp
.data
temp BYTE 13,10,0
.code
	push dx
	mov  dx,OFFSET temp
	call WriteString
	pop  dx
ENDM

;-------------------------------------
ShowRegister MACRO regName, regVal
	        Local str
;
; Show a single register value
;-------------------------------------
.data
str  BYTE  "  &regName=",0
.code
	push eax

	push edx	; save EDX
	mov  dx,OFFSET str
	call WriteString
	pop  edx	; must restore EDX now
IF (TYPE regVal) EQ 4
	mov  eax,regVal	; register value
ELSE
	mov  eax,0
	mov  ax,regVal
ENDIF
	call WriteHex

	pop  eax
ENDM

;-------------------------------------
ShowFlag MACRO flagName,shiftCount
	    LOCAL flagStr, flagVal, L1
;
; Display a single flag value
;-------------------------------------

.data
flagStr BYTE "  &flagName="
flagVal BYTE ?,0

.code
	push ax
	push dx

	mov  ax,flags	; retrieve the flags
	mov  flagVal,'1'
	shr  ax,shiftCount	; shift into carry flag
	jc   L1
	mov  flagVal,'0'
L1:
	mov  dx,OFFSET flagStr	; display flag name and value
	call WriteString

	pop  dx
	pop  ax
ENDM

;--------- END OF MACRO DEFINITIONS ---------------------------


;********************* SHARED DATA AREA **********************
.data?
buffer BYTE 512 dup(?)

;*************************************************************

.code
;------------------------------------------------------
Clrscr PROC
;
; Clears the screen (video page 0) and locates the cursor
; at row 0, column 0.
; Receives: nothing
; Returns:  nothing
;-------------------------------------------------------
	pusha
	mov     ax,0600h    	; scroll window up
	mov     cx,0        	; upper left corner (0,0)
	mov     dx,184Fh    	; lower right corner (24,79)
	mov     bh,7        	; normal attribute
	int     10h         	; call BIOS
	mov     ah,2        	; locate cursor at 0,0
	mov     bh,0        	; video page 0
	mov     dx,0	; row 0, column 0
	int     10h
	popa
	ret
Clrscr ENDP

;-----------------------------------------------------
Crlf PROC
;
; Writes a carriage return / linefeed
; sequence (0Dh,0Ah) to standard output.
;-----------------------------------------------------
	NewLine	; invoke a macro
	ret
Crlf ENDP


;-----------------------------------------------------------
Delay PROC
;
; Create an n-millisecond delay.
; Receives: EAX = milliseconds
; Returns: nothing
; Remarks: May only used under Windows 95, 98, or ME. Does
; not work under Windows NT, 2000, or XP, because it
; directly accesses hardware ports.
; Source: "The 80x86 IBM PC & Compatible Computers" by
; Mazidi and Mazidi, page 343. Prentice-Hall, 1995.
;-----------------------------------------------------------

MsToMicro = 1000000	; convert ms to microseconds
ClockFrequency = 15085	; microseconds per tick
.code
	pushad
; Convert milliseconds to microseconds.
	mov  ebx,MsToMicro
	mul  ebx

; Divide by clock frequency of 15.085 microseconds,
; producing the counter for port 61h.
	mov  ebx,ClockFrequency
	div  ebx	; eax = counter
	mov  ecx,eax

; Begin checking port 61h, watching bit 4 toggle
; between 1 and 0 every 15.085 microseconds.
L1:
	in  al,61h	; read port 61h
	and al,10h	; clear all bits except bit 4
	cmp al,ah	; has it changed?
	je  L1	; no: try again
	mov ah,al	; yes: save status
	dec ecx
	cmp ecx,0	; loop finished yet?
	ja  L1

quit:
	popad
	ret
Delay ENDP


;---------------------------------------------------
DumpMem PROC
	   LOCAL unitsize:word, byteCount:word
;
; Writes a range of memory to standard output
; in hexadecimal.
; Receives: SI = starting OFFSET, CX = number of units,
;           BX = unit size (1=byte, 2=word, or 4=doubleword)
; Returns:  nothing
;---------------------------------------------------
.data
oneSpace   BYTE ' ',0
dumpPrompt BYTE 13,10,"Dump of offset ",0
.code
	pushad

	mov  dx,OFFSET dumpPrompt
	call WriteString
	movzx eax,si
	call  WriteHex
	NewLine

	mov  byteCount,0
	mov  unitsize,bx
	cmp  bx,4	; select output size
	je   L1
	cmp  bx,2
	je   L2
	jmp  L3

L1:	; doubleword output
	mov  eax,[si]
	call WriteHex
	WriteSpace 2
	add  si,bx
	Loop L1
	jmp  L4

L2:	; word output
	mov  ax,[si]	; get a word from memory
	ror  ax,8	; display high byte
	call HexByte
	ror  ax,8	; display low byte
	call HexByte
	WriteSpace 1	; display 1 space
	add  si,unitsize	; point to next word
	Loop L2
	jmp  L4

; Byte output: 16 bytes per line

L3:
	mov  al,[si]
	call HexByte
	inc  byteCount
	WriteSpace 1
	inc  si

	; if( byteCount mod 16 == 0 ) call Crlf

	mov  dx,0
	mov  ax,byteCount
	mov  bx,16
	div  bx
	cmp  dx,0
	jne  L3B
	NewLine
L3B:
	Loop L3
	jmp  L4

L4:
	NewLine
	popad
	ret
DumpMem ENDP

;--------------------------------------------------
Get_Commandtail PROC
;
; Gets a copy of the DOS command tail at PSP:80h.
; Receives: DX contains the offset of the buffer
; that receives a copy of the command tail.
; Returns: CF=1 if the buffer is empty; otherwise,
; CF=0.
; Last update: 11/11/01
;--------------------------------------------------
    push es
	pusha	; save general registers

	mov  ah,62h	; get PSP segment address
	int  21h	; returned in BX
	mov  es,bx	; copied to ES

	mov  si,dx	; point to buffer
	mov  di,81h	; PSP offset of command tail
	mov  cx,0	; byte count
	mov  cl,es:[di-1]	; get length byte
	cmp  cx,0	; is the tail empty?
	je   L2	; yes: exit
	cld	; no: scan forward
	mov  al,20h	; space character
	repz scasb	; scan for non space
	jz   L2	; all spaces found
	dec  di	; non space found
	inc  cx

L1: mov  al,es:[di]	; copy tail to buffer
	mov  [si],al	; pointed to by DS:SI
	inc  si
	inc  di
	loop L1
	clc	; CF=0 means tail found
	jmp  L3

L2:	stc	; set carry: no command tail
L3:	mov byte ptr [si],0	; store null byte
	popa	; restore registers
	pop es
	ret
Get_Commandtail ENDP

;---------------------------------------------------
Gotoxy PROC
;
; Sets the cursor position on video page 0.
; display page.
; Receives: DH,DL = row, column
; Returns: nothing
;---------------------------------------------------
	pusha
	mov ah,2
	mov bh,0
	int 10h
	popa
	ret
Gotoxy ENDP


HexByte PROC
	LOCAL theByte:BYTE
; Display the byte in AL in hexadecimal
; Called only by DumpMem. Updated 9/21/01

	pusha
	mov  theByte,al	; save the byte
	mov  cx,2

HB1:
	rol  theByte,4
	mov  al,theByte
	and  al,0Fh
	mov  bx,OFFSET xtable
	xlat

	; insert hex char in the buffer
	; and display using WriteString
	mov  buffer,al
	mov  [buffer+1],0
	mov  dx,OFFSET buffer
	call WriteString

	Loop HB1

	popa
	ret
HexByte ENDP

;---------------------------------------------------
DumpRegs PROC
;
; Displays EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP in
; hexadecimal. Also displays the Zero, Sign, Carry, and
; Overflow flags.
; Receives: nothing.
; Returns: nothing.
;
; Warning: do not create any local variables or stack
; parameters, because they will alter the EBP register.
;---------------------------------------------------
.data
flags  WORD  ?
saveIP WORD ?
saveSP WORD ?
.code
	pop saveIP	; get current IP
	mov saveSP,sp	; save SP's value at entry
	push saveIP	; replace it on stack
	push eax
	pushfd	; push flags

	pushf	; copy flags to a variable
	pop  flags

	NewLine
	ShowRegister EAX,EAX
	ShowRegister EBX,EBX
	ShowRegister ECX,ECX
	ShowRegister EDX,EDX
	NewLine
	ShowRegister ESI,ESI
	ShowRegister EDI,EDI

	ShowRegister EBP,EBP

	movzx eax,saveSP
	ShowRegister ESP,EAX
	NewLine

	movzx eax,saveIP
	ShowRegister EIP,EAX

	movzx eax,flags
	ShowRegister EFL,EAX

; Show the flags
	ShowFlag CF,1
	ShowFlag SF,8
	ShowFlag ZF,7
	ShowFlag OF,12

	NewLine
	NewLine

	popfd	; restore flags
	pop eax	; restore EAX
	ret
DumpRegs ENDP

;---------------------------------------------------
Get_time PROC
;
; Get the current system time.Input parameter:
; DS:SI points to a TimeRecord structure.
; PRIVATE FUNCTION
;---------------------------------------------------
	 pushad
	 mov ah,2Ch
	 int 21h
	 mov (TimeRecord ptr [si]).hours,ch
	 mov (TimeRecord ptr [si]).minutes,cl
	 mov (TimeRecord ptr [si]).seconds,dh
	 mov (TimeRecord ptr [si]).hhss,dl
	 popad
	 ret
Get_time ENDP

;-----------------------------------------------
Isdigit PROC
;
; Determines whether the character in AL is a
; valid decimal digit.
; Receives: AL = character
; Returns: ZF=1 if AL contains a valid decimal
;   digit; otherwise, ZF=0.
;-----------------------------------------------
	 cmp   al,'0'
	 jb    ID1
	 cmp   al,'9'
	 ja    ID1
	 test  ax,0     		; set ZF = 1
ID1: ret
Isdigit ENDP

;--------------------------------------------------------------
RandomRange PROC
;
; Returns an unsigned pseudo-random 32-bit integer
; in EAX, between 0 and n-1. Input parameter:
; EAX = n.
;--------------------------------------------------------------
	push  bp
	mov   bp,sp
	push  ebx
	push  edx

	mov   ebx,eax  ; maximum value
	call  Random32 ; eax = random number
	mov   edx,0
	div   ebx      ; divide by max value
	mov   eax,edx  ; return the remainder

	pop   edx
	pop   ebx
	pop   bp
	ret
RandomRange ENDP

;--------------------------------------------------------------
Random32  PROC
;
; Returns an unsigned pseudo-random 32-bit integer
; in EAX,in the range 0 - FFFFFFFFh.
;--------------------------------------------------------------
.data
seed  dd 1
.code
	push  edx
	mov   eax, 343FDh
	imul  seed
	add   eax, 269EC3h
	mov   seed, eax    ; save the seed for the next call
	ror   eax,8        ; rotate out the lowest digit (10/22/00)
	pop   edx
	ret
Random32  ENDP

;--------------------------------------------------------
Randomize PROC
;
; Re-seeds the random number generator with the current time
; in seconds.
;
;--------------------------------------------------------
	push eax
	call Seconds_today
	mov  seed,eax
	pop  eax
	ret
Randomize ENDP

;---------------------------------------------------------
ReadChar PROC
;
; Reads one character from standard input and echoes
; on the screen. Waits for the character if none is
; currently in the input buffer.
; Receives: nothing
; Returns:  AL = ASCII code
;----------------------------------------------------------
	mov  ah,1
	int  21h
	ret
ReadChar ENDP

;--------------------------------------------------------
ReadHex PROC
;
; Reads a 32-bit hexadecimal integer from standard input,
; stopping when the Enter key is pressed.
; Receives: nothing
; Returns: EAX = binary integer value
; Remarks: No error checking performed for bad digits
; or excess digits.
; Last update: 11/7/01
;--------------------------------------------------------
.data
HMAX_DIGITS = 128
Hinputarea  BYTE  HMAX_DIGITS dup(0),0
xbtable     BYTE 0,1,2,3,4,5,6,7,8,9,7 DUP(0FFh),10,11,12,13,14,15
numVal      DWORD ?
charVal     BYTE ?

.code
	push ebx
	push ecx
	push edx
	push esi

	mov   edx,OFFSET Hinputarea
	mov   esi,edx		; save in ESI also
	mov   ecx,HMAX_DIGITS
	call  ReadString		; input the string
	mov   ecx,eax           		; save length in ECX

	; Start to convert the number.

B4: mov   numVal,0		; clear accumulator
	mov   ebx,OFFSET xbtable		; translate table

	; Repeat loop for each digit.

B5: mov   al,[esi]	; get character from buffer
	cmp al,'F'	; lowercase letter?
	jbe B6	; no
	and al,11011111b	; yes: convert to uppercase

B6:
	sub   al,30h	; adjust for table
	xlat  	; translate to binary
	mov   charVal,al

⌨️ 快捷键说明

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