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

📄 irvine16.asm

📁 想学习汇编语言的
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	mov   eax,16	; numVal *= 16
	mul   numVal
	mov   numVal,eax
	movzx eax,charVal	; numVal += charVal
	add   numVal,eax
	inc   esi	; point to next digit
	loop  B5	; repeat, decrement counter

	mov  eax,numVal	; return binary result
	pop  esi
	pop  edx
	pop  ecx
	pop  ebx
	ret
ReadHex ENDP


;--------------------------------------------------------
ReadInt PROC uses ebx ecx edx esi
  LOCAL Lsign:DWORD, saveDigit:DWORD
;
; Reads a 32-bit signed decimal integer from standard
; input, stopping when the Enter key is pressed.
; All valid digits occurring before a non-numeric character
; are converted to the integer value. Leading spaces are
; ignored, and an optional leading + or - sign is permitted.

; Receives: nothing
; Returns:  If CF=0, the integer is valid, and EAX = binary value.
;   If CF=1, the integer is invalid and EAX = 0.
;
; Credits: Thanks to Courtney Amor, a student at the UCLA Mathematics
; department, for pointing out improvements that have been
; implemented in this version.
; Last update: 1/27/02
;--------------------------------------------------------
.data
LMAX_DIGITS = 80
Linputarea    BYTE  LMAX_DIGITS dup(0),0
overflow_msgL BYTE  " <32-bit integer overflow>",0
invalid_msgL  BYTE  " <invalid integer>",0
.code

; Input a string of digits using ReadString.

	mov   edx,offset Linputarea
	mov   esi,edx           		; save offset in ESI
	mov   ecx,LMAX_DIGITS
	call  ReadString
	mov   ecx,eax           		; save length in CX
	mov   Lsign,1         		; assume number is positive
	cmp   ecx,0            		; greater than zero?
	jne   L1              		; yes: continue
	mov   eax,0            		; no: set return value
	jmp   L10              		; and exit

; Skip over any leading spaces.

L1:	mov   al,[esi]         		; get a character from buffer
	cmp   al,' '          		; space character found?
	jne   L2              		; no: check for a sign
	inc   esi              		; yes: point to next char
	loop  L1
	jcxz  L8              		; quit if all spaces

; Check for a leading sign.

L2:	cmp   al,'-'          		; minus sign found?
	jne   L3              		; no: look for plus sign

	mov   Lsign,-1        		; yes: sign is negative
	dec   ecx              		; subtract from counter
	inc   esi              		; point to next char
	jmp   L4

L3:	cmp   al,'+'          		; plus sign found?
	jne   L4              		; no: must be a digit
	inc   esi              		; yes: skip over the sign
	dec   ecx              		; subtract from counter

; Test the first digit, and exit if it is nonnumeric.

L3A:mov  al,[esi]		; get first character
	call IsDigit		; is it a digit?
	jnz  L7A		; no: show error message

; Start to convert the number.

L4:	mov   eax,0           		; clear accumulator
	mov   ebx,10          		; EBX is the divisor

; Repeat loop for each digit.

L5:	mov  dl,[esi]		; get character from buffer
	cmp  dl,'0'		; character < '0'?
	jb   L9
	cmp  dl,'9'		; character > '9'?
	ja   L9
	and  edx,0Fh		; no: convert to binary

	mov  saveDigit,edx
	imul ebx		; EDX:EAX = EAX * EBX
	mov  edx,saveDigit

	jo   L6		; quit if overflow
	add  eax,edx         		; add new digit to AX
	jo   L6		; quit if overflow
	inc  esi              		; point to next digit
	jmp  L5		; get next digit

; Overflow has occured, unlesss EAX = 80000000h
; and the sign is negative:

L6: cmp  eax,80000000h
	jne  L7
	cmp  Lsign,-1
	jne  L7		; overflow occurred
	jmp  L9		; the integer is valid

; Choose "integer overflow" messsage.

L7:	mov  edx,OFFSET overflow_msgL
	jmp  L8

; Choose "invalid integer" message.

L7A:
	mov  edx,OFFSET invalid_msgL

; Display the error message pointed to by EDX.

L8:	call WriteString
	call Crlf
	stc		; set Carry flag
	mov  eax,0            		; set return value to zero
	jmp  L10		; and exit

L9: imul Lsign           		; EAX = EAX * sign

L10:ret
ReadInt ENDP


;--------------------------------------------------------
ReadString PROC
; Reads a string from standard input and places the
; characters in a buffer. Reads past end of line,
; and removes the CF/LF from the string.
; Receives: DS:DX points to the input buffer,
;           CX = maximum characters that may be typed.
; Returns:  AX = size of the input string.
; Comments: Stops when the Enter key (0Dh) is pressed.
;--------------------------------------------------------
	push cx		; save registers
	push si
	push cx		; save digit count again
	mov  si,dx		; point to input buffer

L1:	mov  ah,1		; function: keyboard input
	int  21h		; DOS returns char in AL
	cmp  al,0Dh		; end of line?
	je   L2		; yes: exit
	mov  [si],al		; no: store the character
	inc  si		; increment buffer pointer
	loop L1		; loop until CX=0

L2:	mov  byte ptr [si],0		; end with a null byte
	pop  ax		; original digit count
	sub  ax,cx		; AX = size of input string
	pop  si		; restore registers
	pop  cx
	ret
ReadString ENDP


;-------------------------------------------------------
Seconds_today PROC
;
; Returns a count of the number of seconds that
; have elapsed today. Output: EAX contains the
; return value. Range: 0 - 86,399
;--------------------------------------------------------
.data
timerec TimeRecord <>
saveSec  DWORD  ?

.code
	push ebx
	push si

	mov  si,OFFSET timerec
	call Get_time

 ; calculate # seconds based on hours.
	xor  eax,eax
	mov  al,(TimeRecord ptr [si]).hours
	mov  ebx,3600
	mul  ebx
	mov  saveSec,eax

 ; multiply minutes by 60

	xor  eax,eax
	mov  al,(TimeRecord ptr [si]).minutes
	mov  ebx,60
	mul  ebx
	add  saveSec,eax

	xor  eax,eax
	mov  al,(TimeRecord ptr [si]).seconds
	add  eax,saveSec

	pop  si
	pop  ebx
	ret
Seconds_today ENDP


;----------------------------------------------------------
Str_compare PROC USES ax dx si di,
	string1:PTR BYTE,
	string2:PTR BYTE
;
; Compare two strings.
; Returns nothing, but the Zero and Carry flags are affected
; exactly as they would be by the CMP instruction.
; Last update: 1/18/02
;-----------------------------------------------------
    mov  si,string1
    mov  di,string2

L1: mov  al,[si]
    mov  dl,[di]
    cmp  al,0    			; end of string1?
    jne  L2      			; no
    cmp  dl,0    			; yes: end of string2?
    jne  L2      			; no
    jmp  L3      			; yes, exit with ZF = 1

L2: inc  si      			; point to next
    inc  di
    cmp  al,dl   			; chars equal?
    je   L1      			; yes: continue loop
                 			; no: exit with flags set
L3: ret
Str_compare ENDP

;---------------------------------------------------------
Str_copy PROC USES ax cx si di,
 	source:PTR BYTE, 		; source string
 	target:PTR BYTE		; target string
;
; Copy a string from source to target.
; Requires: the target string must contain enough
;           space to hold a copy of the source string.
; Last update: 1/18/02
;----------------------------------------------------------
	INVOKE Str_length,source 		; AX = length source
	mov cx,ax		; REP count
	inc cx         		; add 1 for null byte
	mov si,source
	mov di,target
	cld               		; direction = up
	rep movsb      		; copy the string
	ret
Str_copy ENDP

;---------------------------------------------------------
Str_length PROC USES di,
	pString:PTR BYTE	; pointer to string
;
; Return the length of a null-terminated string.
; Receives: pString - pointer to a string
; Returns: AX = string length
; Last update: 1/18/02
;---------------------------------------------------------
	mov di,pString
	mov ax,0     	; character count
L1:
	cmp byte ptr [di],0	; end of string?
	je  L2	; yes: quit
	inc di	; no: point to next
	inc ax	; add 1 to count
	jmp L1
L2: ret
Str_length ENDP


;-----------------------------------------------------------
Str_trim PROC USES ax cx di,
	pString:PTR BYTE,		; points to string
	char:BYTE		; char to remove
;
; Remove all occurences of a given character from
; the end of a string.
; Returns: nothing
; Last update: 1/18/02
;-----------------------------------------------------------
	mov  di,pString
	INVOKE Str_length,di		; returns length in AX
	cmp  ax,0		; zero-length string?
	je   L2		; yes: exit
	mov  cx,ax		; no: counter = string length
	dec  ax
	add  di,ax		; DI points to last char
	mov  al,char		; char to trim
	std		; direction = reverse
	repe scasb		; skip past trim character
	jne  L1		; removed first character?
	dec  di		; adjust DI: ZF=1 && ECX=0
L1:	mov  BYTE PTR [di+2],0		; insert null byte
L2:	ret
Str_trim ENDP

;---------------------------------------------------
Str_ucase PROC USES ax si,
	pString:PTR BYTE
; Convert a null-terminated string to upper case.
; Receives: pString - a pointer to the string
; Returns: nothing
; Last update: 1/18/02
;---------------------------------------------------
	mov si,pString
L1:
	mov al,[si]		; get char
	cmp al,0		; end of string?
	je  L3		; yes: quit
	cmp al,'a'		; below "a"?
	jb  L2
	cmp al,'z'		; above "z"?
	ja  L2
	and BYTE PTR [si],11011111b		; convert the char

L2:	inc si		; next char
	jmp L1

L3: ret
Str_ucase ENDP

;------------------------------------------------------
WaitMsg PROC
;
; Displays "Press any key to continue"
; Receives: nothing
; Returns: nothing
;------------------------------------------------------
.data
waitmsgstr BYTE "Press any key to continue...",0
.code
	push dx
	mov  dx,OFFSET waitmsgstr
	call WriteString
	call ReadChar
	NewLine
	pop  dx
	ret
WaitMsg ENDP

;------------------------------------------------------
WriteBin PROC
;
; Writes a 32-bit integer to standard output in
; binary format.
; Receives: EAX = the integer to write
;------------------------------------------------------
.code
	push  eax
	push  ecx
	push  edx
	mov   cx,32	; number of bits in AX
	mov   si,OFFSET buffer

WB1:
	shl   eax,1	; shift EAX left into Carry flag
	mov   byte ptr [si],'0'	; choose '0' as default digit
	jnc   WB2	; if no carry, then jump to L2
	mov   byte ptr [si],'1'	; else move '1' to DL

WB2:
	inc   si
	loop  WB1	; shift another bit to left

	mov  byte ptr [si],0	; insert null byte at end
	mov  dx,OFFSET buffer	; display the buffer
	call WriteString

	pop  edx
	pop  ecx
	pop  eax
	ret
WriteBin ENDP


;------------------------------------------------------
WriteChar PROC
;
; Write a character to standard output
; Recevies: AL = character
;------------------------------------------------------
	push ax
	push dx
	mov  ah,2
	mov  dl,al
	int  21h
	pop  dx
	pop  ax
	ret
WriteChar ENDP


;-----------------------------------------------------
WriteDec PROC
;
; Writes an unsigned 32-bit decimal number to
; standard output. Input parameters: EAX = the
; number to write.
;
;------------------------------------------------------
.data
; There will be as many as 10 digits.
BUFFER_SIZE = 12

bufferL BYTE BUFFER_SIZE dup(?),0
xtable BYTE "0123456789ABCDEF"

.code
	pushad               ; save all 32-bit data registers
	mov   cx,0           ; digit counter
	mov   di,OFFSET bufferL
	add   di,(BUFFER_SIZE - 1)
	mov   ebx,10	; decimal number base

WI1:
	mov   edx,0          ; clear dividend to zero
	div   ebx            ; divide EAX by the radix

	xchg  eax,edx        ; swap quotient, remainder
	call  AsciiDigit     ; convert AL to ASCII
	mov   [di],al        ; save the digit
	dec   di             ; back up in buffer
	xchg  eax,edx        ; swap quotient, remainder

	inc   cx             ; increment digit count
	or    eax,eax        ; quotient = 0?
	jnz   WI1            ; no, divide again

	; Display the digits (CX = count)
WI3:
	inc   di
	mov   dx,di
	call  WriteString

WI4:
	popad	; restore 32-bit registers
	ret
WriteDec ENDP

; Convert AL to an ASCII digit.

AsciiDigit PROC private
	push  bx
	mov   bx,OFFSET xtable
	xlat
	pop   bx
	ret
AsciiDigit ENDP

;------------------------------------------------------
WriteHex PROC
;
; Writes an unsigned 32-bit hexadecimal number to
; standard output.
; Input parameters: EAX = the number to write.
;
;------------------------------------------------------

DISPLAY_SIZE = 8          ; total number of digits to display

.data
bufferLH BYTE DISPLAY_SIZE dup(?),0

.code
	pushad               ; save all 32-bit data registers
	mov   cx,0           ; digit counter
	mov   di,OFFSET bufferLH
	add   di,(DISPLAY_SIZE - 1)
	mov   ebx,16	     ; hexadecimal base

WLH1:
	mov   edx,0          ; clear dividend to zero
	div   ebx            ; divide EAX by the radix

	xchg  eax,edx        ; swap quotient, remainder
	call  AsciiDigit     ; convert AL to ASCII
	mov   [di],al        ; save the digit
	dec   di             ; back up in buffer
	xchg  eax,edx        ; swap quotient, remainder

	inc   cx             ; increment digit count
	or    eax,eax        ; quotient = 0?
	jnz   WLH1           ; no, divide again

	; Insert leading zeros

	mov   ax,DISPLAY_SIZE
	sub   ax,cx
	jz    WLH3           ; display now if no leading zeros required
	mov   cx,ax          ; CX = number of leading zeros to insert

WLH2:
	mov   byte ptr [di],'0'   ; insert a zero
	dec   di                  ; back up
	loop  WLH2                ; continue the loop

	; Display the digits

WLH3:
	mov   cx,DISPLAY_SIZE
	inc   di
	mov   dx,di
	call  WriteString

	popad     ; restore 32-bit registers
	ret
WriteHex ENDP


;-----------------------------------------------------
WriteInt PROC
;
; Writes a 32-bit signed binary integer to standard output
; in ASCII decimal.
; Receives: EAX = the integer
; Returns:  nothing
; Comments: Displays a leading sign, no leading zeros.
;-----------------------------------------------------
WI_Bufsize = 12
true  =   1
false =   0
.data
buffer_B  BYTE  WI_Bufsize dup(0),0  ; buffer to hold digits
neg_flag  BYTE  ?

.code
	 pushad

	 mov   neg_flag,false    ; assume neg_flag is false
	 or    eax,eax             ; is AX positive?
	 jns   WIS1              ; yes: jump to B1
	 neg   eax                ; no: make it positive
	 mov   neg_flag,true     ; set neg_flag to true

WIS1:
	 mov   cx,0              ; digit count = 0
	 mov   di,OFFSET buffer_B
	 add   di,(WI_Bufsize-1)
	 mov   ebx,10             ; will divide by 10

WIS2:
	 mov   edx,0              ; set dividend to 0
	 div   ebx                ; divide AX by 10
	 or    dl,30h            ; convert remainder to ASCII
	 dec   di                ; reverse through the buffer
	 mov   [di],dl           ; store ASCII digit
	 inc   cx                ; increment digit count
	 or    eax,eax             ; quotient > 0?
	 jnz   WIS2              ; yes: divide again

	 ; Insert the sign.

	 dec   di	; back up in the buffer
	 inc   cx               	; increment counter
	 mov   byte ptr [di],'+' 	; insert plus sign
	 cmp   neg_flag,false    	; was the number positive?
	 jz    WIS3              	; yes
	 mov   byte ptr [di],'-' 	; no: insert negative sign

WIS3:	; Display the number
	mov  dx,di
	call WriteString

	popad
	ret
WriteInt ENDP


;--------------------------------------------------------
WriteString PROC
; Writes a null-terminated string to standard output
; Receives: DS:DX points to the string
; Returns: nothing
;--------------------------------------------------------
	pusha
	push ds           		; set ES to DS
	pop  es
	mov  di,dx        		; ES:DI = string ptr
	INVOKE Str_length, DX   		; AX = string length
	mov  cx,ax        		; CX = number of bytes
	mov  ah,40h       		; write to file or device
	mov  bx,1         		; standard output handle
	int  21h          		; call MS-DOS
	popa
	ret
WriteString ENDP

END

⌨️ 快捷键说明

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