📄 a1.asm
字号:
;----------------------------------------------------------------------------
; CPSC 325 Program
; A1
; Author: Xuan Wang
; Date: Jan 23, 2006
;----------------------------------------------------------------------------
[GLOBAL mystart] ; export the start address
;----------------------------------------------------------------------------
[SECTION .text]
;----------------------------------------------------------------------------
; code belongs in this section starting here
extern _printf ;inport printf function from c
mystart:
call input1 ; call the input base function, the base is stored in bbuffer1
mov bl, bl ; make sure the value within bl is correct
movzx ecx, byte [bbuffer1+1] ; the length of number within basebuffer1 is in ecx
mov byte [bbuffer1+2+ecx], 0 ; move to the end of basebuffer1
second1:
call number ; get the input number which is stored in inbuffer
movzx ecx, byte [inbuffer+1] ; the length of number within inbuffer is in ecx
mov byte [inbuffer+2+ecx], 0 ; move to the end of inbuffer
mov eax, edx ; store the input number in eax
call input2 ; call the output base function
mov ecx, ecx ; the output base is stored in ecx
push ecx ; push output base onto the stack
movzx ecx, byte [bbuffer2+1] ; the length of number within basebuffer2 is in ecx
mov byte [bbuffer2+2+ecx], 0 ; move to the end of basebuffer2
pop ecx ; pop ecx out of the stack
mov ebx, outbuffer ; store the address of outbuffer in ebx
call number1 ; call the converting ascii to binary routine
movzx ecx, byte [outbuffer+1] ; the length of number within outbuffer is in ecx
mov byte [outbuffer+2+ecx], 0 ; move to the end of outbuffer
mov eax, ebx ; store the address of outbuffer in eax
push eax ; push the outbuffer onto the stack
mov eax, bbuffer2+2 ; store the output base in eax
push eax ; push the output base onto the stack
mov eax, inbuffer+2 ; store the input number in eax
push eax ; push the input number onto the stack
mov eax, bbuffer1+2 ; store the input base in eax
push eax ; push the input base onto the stack
push dword prompt4 ; push the output string onto the stack
call _printf ; output on the screen
;call countout
add esp, 20 ; add the offset
jmp second1 ; let the user input the next input base
quit2:
ret ; quit the program
;-----------------------------------------
; base convert routine
base:
mov bl, 0 ; clear bl
mov bh, 10 ; clear bh
top:
lodsb ; get the next character
sub al, '0' ; convert the input number from ascii to int
mov dl, al ; store the input number in dl
mov al, bl ; store bl in al
mul bh ; al=al*bh
add al, dl ; al=al+dl
mov bl, al ; store al in bl
loop top ; loop
ret
;----------------------------------------
;input1 routine to store the input base,
;also do the error checking
input1:
push eax ;push the local registers
push edx
push esi
push ecx
looop:
mov ah, 09h ; select write string function
mov edx, prompt1 ; output "ENTER THE BASE OF THE NUMBER TO BE ENTERED OR Q to quit" onto the screen
int 0f1h ; call OS interrupt 0F1H
mov byte [bbuffer1], 98 ; buffer can hold 98 characters
mov byte [bbuffer1+1], 0 ; reuse 0 characters from last input
mov ah, 0ah ; select buffered input function
mov edx, bbuffer1 ; put buffer address in EDX
int 0f1h ; call OS interrupt 0F1H
mov ah, 02h ; select write character function
mov dl, 10 ; output a newline
int 0f1h ; call OS interrupt 0F1H
cmp byte [bbuffer1+2], 'Q' ; check for quit program
je quit2 ; jump to the end of the program
movzx ecx, byte [bbuffer1+1] ; load ECX with number of characters read
mov esi, bbuffer1+2 ; load adress of input text into ES
;cmp [esi], 'Q'
;je endpro
cld ; clear the direction flag to the front
call base ; call convert base rountine
cmp bl, 2 ; check the range of input base, which should be
jb looop ; within the range 2-36, if out of this range
cmp bl, 35 ; let the user input the input base again
ja looop
mov ah, 02h ; select write character function
mov dl, 13 ; output a carriage return
int 0f1h ; call OS interrupt 0F1H
jmp fini2 ; jump to fini2
fini2:
pop ecx ; pop out registers
pop esi
pop edx
pop eax
ret
;----------------------------------------
;input2 routine to store the output base,
;also do the error checking
input2:
push eax ; push local registers
push esi
push edx
looop1:
mov ah, 09h ; select write string function
mov edx, prompt3 ; output "ENTER BASE OF OUTPUT VALUE" onto the screen
int 0f1h ; call OS interrupt 0F1H
mov byte [bbuffer2], 98 ; buffer can hold 98 characters
mov byte [bbuffer2+1], 0 ; reuse 0 characters from last input
mov ah, 0ah ; select buffered input function
mov edx, bbuffer2 ; put buffer address in EDX
int 0f1h ; call OS interrupt 0F1H
mov ah, 02h ; select write character function
mov dl, 10 ; output a newline
int 0f1h ; call OS interrupt 0F1H
movzx ecx, byte [bbuffer2+1] ; load ECX with number of characters read
mov esi, bbuffer2+2 ; load adress of input text into ESI
cld ; set direction flag to go forwards
call base ; call convert base rountine
cmp bl, 2 ; check the range of input base, which should be
jb looop1 ; within the range 2-36, if out of this range
cmp bl, 35 ; let the user input the input base again
ja looop1
mov cl, bl ; store output base to cl
mov ah, 02h ; select write character function
mov dl, 13 ; output a carriage return
int 0f1h ; call OS interrupt 0F1H
pop edx ; pop registers
pop esi
pop eax
ret
;-------------------------------------------
;number routine to store the input number,
;check the input number
;covert to binary
number:
push eax ; push the local registers
push esi
push ecx
again:
mov ah, 09h ; select write string function
mov edx, prompt2 ; output "ENTER A NUMBER or Q to quit" on the screen
int 0f1h ; call OS interrupt 0F1H
mov byte [inbuffer], 98 ; buffer can hold 98 characters
mov byte [inbuffer+1], 0 ; reuse 0 characters from last input
mov ah, 0ah ; select buffered input function
mov edx, inbuffer ; put buffer address in EDX
int 0f1h ; call OS interrupt 0F1H
mov ah, 02h ; select write character function
mov dl, 10 ; output a newline
int 0f1h ; call OS interrupt 0F1H
;cmp byte [inbuffer+2], 'Q'
;je near endpro
;cmp byte [inbuffer+2], 'q'
;je endpro
movzx ecx, byte [inbuffer+1] ; load ECX with number of characters read
mov esi, inbuffer+2 ; load adress of input text into ESI
cld ; set direction flag to go forwards
mov bh, 0 ; clear bh
mov dx, 0 ; clear dx
cmp bl, 9 ; compare the input number with 9
ja over9 ; jump to over9 if the number>9
top2:
lodsb ; get the next character
sub al,'0' ; convert the number from ascii to int
cmp al, 0 ; compare the input number with 0
jb again ; if the number<0, the input is invalid, so go back to the input number command
cmp al, bl ; compare the number with 9
ja again ; if the number > 9, the input is invalid, go back to the input number command
mov bh, al ; store the input number in bh
mov ax, dx ; store dx to ax
mul bl ; ax=ax*bl
push ecx ; push ecx in the stack
mov cl, bh ; store bh to cl
mov edx, ecx ; store ecx to edx
pop ecx ; pop ecx out of the stack
add edx, eax ; edx=edx+eax
loop top2 ; loop
jmp fini1 ; jump to fini1
over9:
call above9 ; if the input number>9 jump to above9 rountine
fini1: ; pop the registers
pop ecx
pop esi
pop eax
ret
;--------------------------------------------------------
;--------------------------------------------------------
;above 9 rountine
above9:
second: lodsb ; get the next character
sub al, '0' ; convert the number from ascii to int
cmp al, 0 ; compare the input number with 0
jb near again ; if number<0, the input is invalid, so go back to the input number command
cmp al, 9 ; compare the number with 9
ja next1 ; if number>9 jump to next1
mov bh, al ; store al to bh
mov ax, dx ; store dx to ax
mul bl ; ax=ax*bl
push ecx ; push ecx onto the stack
mov cl, bh ; store bh to cl
mov edx, ecx ; store ecx to edx
pop ecx ; pop ecx out of the stack
add edx, eax ; edx=edx+eax
loop second ; loop
jmp near fini1 ; jump to fini1
next1:
sub al, 16 ; al=al-16, check if the number is within the range A-Z
cmp al, 0 ; if the number < 0 which means it falls in the range between 9-A, error input
jb near again ; let the user input the number again
cmp al, 25 ; check the number if it is above the range A-Z, go to next2
ja next2
add al, 10 ; covert A-Z to int number
cmp al, bl ; compare the number with 9
ja near again ; if number>9, input is invalid, let the user input number again
mov bh, al ; store al to bh
mov ax, dx ; store dx to ax
mul bl ; ax=ax*bl
push ecx ; push ecx onto the stack
mov cl, bh ; store bh to cl
mov edx, ecx ; store ecx to edx
pop ecx ; pop ecx out of the stack
add edx, eax ; edx=edx+eax
loop second ; loop
jmp near fini1 ; jump to fini1
next2:
sub al, 31 ; al=al-31, check if the number is within the range a-z
cmp al, 0 ; if the number<0 which means it falls int eh range between Z-a, error input
jb near again ; let the user input the number again
cmp al, 25 ; if the number > 25, which means it falls out of the range a-z, error input
ja near again ; let the user input the number again
add al, 10 ; conver a-z to in number
cmp al, bl ; compare the number with 9
ja near again ; if number>9, input is invalid, let the user input number again
mov bh, al ; store al to bh
mov ax, dx ; store dx to ax
mul bl ; ax=ax*bl
push ecx ; push ecx onto the stack
mov cl, bh ; store bh to cl
mov edx, ecx ; store ecx to edx
pop ecx ; pop ecx out the stack
add edx, eax ; edx=edx+eax
loop second ; loop
jmp near fini1 ; jump to fini1
ret
;------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------
; number1 routine convert binary to ASCII
number1:
push edx ; push local registers
push edi
mov edi, ebx ; store the address of output string in edi
test eax, 0ffffffffh ; check the negative of input number
jns positive ; jump to positive
mov byte [edi], '-' ; store minus sign in output string
inc edi ; increment edi
neg eax ; negate input number
positive:
push dword 0 ; push marker, keeping stack dword aligned
looop2:
mov edx, 0 ; clear edx
div ecx ; divide base into R:Q where EDX will
; contain the remainder and EAX the
; dividend then quotient
cmp edx, 9
jae letter
add edx, '0' ; most convenient to do ASCII conversion here
; add ASCII '0'
jmp puush ; so we can terminate our popping off stack
letter:
add edx, -10 ; convert the number back to ascii
add edx, 'A'
puush:
push edx ; push the character
test eax, 0ffffffffh ; if quotient is zero we are done
jnz looop
outloop:
pop eax ; pop digits
mov [edi], al ; and store
inc edi ; the null is also popped and stored
test al, 0ffh ; test for null
jnz outloop
pop edi ; transparency
pop edx
ret
;----------------------------------------------------------------------------
[SECTION .data]
;----------------------------------------------------------------------------
; all initialized data variables and constant definitions go here
prompt1 db "ENTER THE BASE OF THE NUMBER TO BE ENTERED OR Q to quit",
13, 10, "> $"
prompt2 db "ENTER A NUMBER or Q to quit", 13, 10, "> $"
prompt3 db "ENTER BASE OF OUTPUT VALUE", 13, 10, "> $"
prompt4 db "THE BASE %s NUMBER %s EXPRESSED IN BASE %s.it is: %s. ",13,
10,0,'$'
;----------------------------------------------------------------------------
[SECTION .bss]
;----------------------------------------------------------------------------
; all uninitialized data elements go here
bbuffer1 resb 100 ; buffer to store input base
inbuffer resb 100 ; buffer to store input number
bbuffer2 resb 100 ; buffer to store output base
outbuffer resb 100 ; buffer to store the output
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -