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

📄 io.asm

📁 北京航空航天大学计算机系要求的编译器大作业。大概6000行代码。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; implementation of I/O procedures called by macros in io.obj
; flat memory model version
; author:  R. Detmer
; last revised:  6/98

.386
.MODEL FLAT, syscall

PUBLIC itoaproc, atoiproc, dtoaproc, atodproc, outproc, inproc

.CODE

; itoaproc(source, dest)
; convert integer (source) to string of 6 characters at given destination address
itoaproc    PROC   NEAR32
            push   ebp                  ; save base pointer
            mov    ebp, esp             ; establish stack frame
            push   eax                  ; Save registers
            push   ebx                  ;   used by
            push   ecx                  ;   procedure
            push   edx
            push   edi
            pushf                      ; save flags

            mov    ax, [ebp+12]        ; first parameter (source integer)
            mov    edi, [ebp+8]        ; second parameter (dest offset)
ifSpecial:  cmp    ax,8000h            ; special case -32,768?
            jne    EndIfSpecial        ; if not, then normal case
            mov    BYTE PTR [edi],'-'  ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'3'  ;   for -32,768
            mov    BYTE PTR [edi+2],'2'
            mov    BYTE PTR [edi+3],'7'
            mov    BYTE PTR [edi+4],'6'
            mov    BYTE PTR [edi+5],'8'
            jmp    ExitIToA            ; done with special case
EndIfSpecial:

            mov    dx, ax              ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,5               ;   first five
            cld                        ;   bytes of
            rep stosb                  ;   destination field    

            mov    ax, dx              ; copy source number
            mov    cl,' '              ; default sign (blank for +)
IfNeg:      cmp    ax,0                ; check sign of number
            jge    EndIfNeg            ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    ax                  ; number in AX now >= 0
EndIfNeg:

            mov    bx,10               ; divisor

WhileMore:  mov    dx,0                ; extend number to doubleword
            div    bx                  ; divide by 10
            add    dl,30h              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    ax,0                ; check quotient
            jnz    WhileMore           ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitIToA:   popf                       ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx 
            pop    eax
            pop    ebp 
            ret    6                   ;exit, discarding parameters
itoaproc    ENDP

; dtoaproc(source, dest)
; convert double (source) to string of 11 characters at given offset in DS (dest)
dtoaproc    PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            push   eax                 ; Save registers
            push   ebx                 ;   used by
            push   ecx                 ;   procedure
            push   edx
            push   edi
            pushf                      ; save flags

            mov    eax, [ebp+12]         ; first parameter (source double)
            mov    edi, [ebp+8]          ; second parameter (dest addr)
ifSpecialD: cmp    eax,80000000h       ; special case -2,147,483,648?
            jne    EndIfSpecialD       ; if not, then normal case
            mov    BYTE PTR [edi],'-'   ; manually put in ASCII codes
            mov    BYTE PTR [edi+1],'2' ;   for -2,147,483,648
            mov    BYTE PTR [edi+2],'1'
            mov    BYTE PTR [edi+3],'4'
            mov    BYTE PTR [edi+4],'7'
            mov    BYTE PTR [edi+5],'4'
            mov    BYTE PTR [edi+6],'8'
            mov    BYTE PTR [edi+7],'3'
            mov    BYTE PTR [edi+8],'6'
            mov    BYTE PTR [edi+9],'4'
            mov    BYTE PTR [edi+10],'8'
            jmp    ExitDToA            ; done with special case
EndIfSpecialD:

            mov    edx, eax            ; save source number

            mov    al,' '              ; put blanks in
            mov    ecx,10              ;   first ten
            cld                        ;   bytes of
            rep stosb                  ;   destination field    

            mov    eax, edx            ; copy source number
            mov    cl,' '              ; default sign (blank for +)
IfNegD:     cmp    eax,0               ; check sign of number
            jge    EndIfNegD           ; skip if not negative
            mov    cl,'-'              ; sign for negative number
            neg    eax                 ; number in EAX now >= 0
EndIfNegD:

            mov    ebx,10              ; divisor

WhileMoreD: mov    edx,0               ; extend number to doubleword
            div    ebx                 ; divide by 10
            add    dl,30h              ; convert remainder to character
            mov    [edi],dl            ; put character in string
            dec    edi                 ; move forward to next position
            cmp    eax,0               ; check quotient
            jnz    WhileMoreD          ; continue if quotient not zero

            mov    [edi],cl            ; insert blank or "-" for sign

ExitDToA:   popf                       ; restore flags and registers
            pop    edi
            pop    edx
            pop    ecx
            pop    ebx 
            pop    eax
            pop    ebp 
            ret    8                   ;exit, discarding parameters
dtoaproc    ENDP

; atoiproc(source)
; Procedure to scan data segment starting at source address, interpreting 
; ASCII characters as an integer value which is returned in AX.

; Leading blanks are skipped.  A leading - or + sign is acceptable.
; Digit(s) must immediately follow the sign (if any).
; Memory scan is terminated by any non-digit, and the address of 
; the terminating character is in ESI.

; The following flags are affected:
;   AC is undefined
;   PF, SF and ZF reflect sign of number returned in AX.
;   CF reset to 0
;   OF set to indicate error.  Possible error conditions are:
;     - no digits in input
;     - value outside range -32,768 to 32,767
;   (AX) will be 0 if OF is set.

atoiproc    PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            sub    esp, 2              ; local space for sign
            push   ebx                 ; Save registers
            push   ecx
            push   edx
            pushf                      ; save flags

            mov    esi,[ebp+8]         ; get parameter (source addr)

WhileBlank: cmp    BYTE PTR [esi],' '  ; space?
            jne    EndWhileBlank       ; exit if not
            inc    esi                 ; increment character pointer
            jmp    WhileBlank          ; and try again
EndWhileBlank:

            mov    ax,1                ; default sign multiplier
IfPlus:     cmp    BYTE PTR [esi],'+'  ; leading + ?
            je     SkipSign            ; if so, skip over
IfMinus:    cmp    BYTE PTR [esi],'-'  ; leading - ?
            jne    EndIfSign           ; if not, save default +
            mov    ax,-1               ; -1 for minus sign
SkipSign:   inc    esi                 ; move past sign
EndIfSign:

            mov    [ebp-2],ax          ; save sign multiplier
            mov    ax,0                ; number being accumulated
            mov    cx,0                ; count of digits so far

WhileDigit: cmp    BYTE PTR [esi],'0'  ; compare next character to '0'
            jl     EndWhileDigit       ; not a digit if smaller than '0'
            cmp    BYTE PTR [esi],'9'  ; compare to '9'
            jg     EndWhileDigit       ; not a digit if bigger than '9'
            imul   ax,10               ; multiply old number by 10
            jo     overflow            ; exit if product too large
            mov    bl,[esi]            ; ASCII character to BL
            and    bx,000Fh            ; convert to single-digit integer
            add    ax,bx               ; add to sum
            jc     overflow            ; exit if sum too large
            inc    cx                  ; increment digit count
            inc    esi                 ; increment character pointer
            jmp    WhileDigit          ; go try next character
EndWhileDigit:

            cmp    cx,0                ; no digits?
            jz     overflow            ; if so, set overflow error flag

; if value is 8000h and sign is '-',  want to return 8000h (-32,768)

            cmp    ax,8000h            ; 8000h ?
            jne    TooBig?
            cmp    WORD PTR [ebp-2],-1 ; multiplier -1 ?
            je     ok1                 ; if so, return 8000h

TooBig?:    test   ax,ax               ; check sign flag
            jns    ok                  ; will be set if number > 32,767

overflow:   pop    ax                  ; get flags
            or     ax,0000100001000100B  ; set overflow, zero & parity flags
            and    ax,1111111101111110B  ; reset sign and carry flags
            push   ax                  ; push new flag values
            mov    ax,0                ; return value of zero
            jmp    AToIExit            ; quit

⌨️ 快捷键说明

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