화면에서 10진수 숫자(0~65535 사이의 값) 3개를, 차례로 입력 받은 뒤, 그 중에 가장 큰 값을 16진수로 화면에 출력한다
어셈블리어는 입력을 받을시 문자열로 저장하기 때문에 입력을 받아서 숫자로 변환을 해주어야 한다
입력을 받기위해서는 인터럽트 21H에서 0AH를 호출하면 된다
문자열이 입력될 때는 [버퍼 크기] + [문자열 길이] + [입력된 문자열] 순으로 저장되기 때문에 이를 염두해두면서 코딩을 해야한다
사용할 변수들을 데이터로 저장해준다
CRLF DB 0AH, 0DH, "$" ; 줄바꿈을 해주는 역할
msg1 DB "First Number: ", "$" ; 출력할 문자열을 미리 저장
msg2 DB "Second Number: ", "$"
msg3 DB "Third Number: ", "$"
msg4 DB "Largest Number: ", "$"
msgs DW OFFSET msg1, OFFSET msg2, OFFSET msg3, OFFSET msg4
max_len DB 6 ; 문자열의 버퍼의 크기를 저장
act_len DB ? ; 문자열의 길이를 저장
str1 DB 6 dup(0) ; 입력된 문자열을 저장
array DW 0, 0, 0 ; 숫자를 저장할 배열
입력을 받으면 문자 '0'만큼을 빼서 숫자 값을 구해준다
MOV BX, 0 ; 인덱스와 반복 횟수로 사용할 레지스터
INPUT:
MOV DX, msgs[bx]
MOV AH, 9
INT 21H
MOV DX, OFFSET max_len ; 문자열을 입력 받는다.
MOV AH, 10 로 저장
INT 21H
MOV DX, OFFSET CRLF
MOV AH, 9
INT 21H
MOV SI, OFFSET str1
ADD SI, 4 ; 최대 5자리수이므로 1의 자리로 주소 이동
mov CX, 1 ; 자릿수만큼 곱해주기 위해 cx 1을 줌
CAST:
MOV AX, 0
MOV AL, [si]
CMP AL, '0' ; 문자 0과 비교하여 더 작으면 점프
JB pass
SUB AX, '0' ; 그렇지 않을 경우 문자 0만큼 빼서 숫자 값을 구함
MUL CX ; 자릿수에 해당하는 값을 곱해준다
ADC array[bx], AX
MOV AX, CX
MOV CX, 10
MUL CX
MOV CX, AX
PASS:
DEC SI ; 주소를 하나씩 줄여가며 계산
CMP SI, OFFSET str1 ; 시작 주소와 같으면 탈출한다
JB cast_end
JMP cast
CAST_END:
ADD BX, 2 ; word 단위 이므로 인덱스는 2씩 증가
CMP BX, 6
JE input_end
JMP input
INPUT_END:
조건 점프를 사용하여 가장 큰 수를 구할 수 있다
MOV BX, array[0] ; 첫번째 수 BX에 저장
CMP BX, array[2]
JAE comp ; 같거나 큰 경우 comp로 점프
MOV BX, array[2] ; 아니면 BX에 두번째 수를 저장
COMP: CMP BX, array[4] ; bx와 세번째 숫자를 비교한다
MOV cx, 4
JAE hex ; hex 구간을 4번 반복하기 위해 CX에 4를 준다
MOV BX, array[4] ; 비교후 가장 큰 수가 BX에 저장됨
출력을 위해 아스키코드를 이용하여 16진수에 해당하는 문자로 변환해준다
HEX:
MOV AX, BX
SHR BX, 1 ; 오른쪽으로 한바이트 쉬프트 해둔다
SHR BX, 1
SHR BX, 1
SHR BX, 1
AND AX, 0fH ; 하위 4비트를 0xf와 and연산하여 값을 구한다
CMP AX, 0aH ; 값이 10이 넘으면 알파벳으로 표기하므로 비교
JL save
ADD AX, 7 ; 아스키코드로 문자 9는 57, A는 65이므로
; 10이상이면 7을 더해주어 알파벳출력이 가능하게 해준다
SAVE:
PUSH AX ; 변환된 ax를 스택에 넣어준다
LOOP hex
출력을 하기위해서는 인터럽트 21H에서 02H와 09H를 호출하면 된다
02H는 한 문자를 출력할때 사용하고 09H는 문자열을 출력할 때 사용한다
스택에 저장해둔 값을 POP하여 문자로 변환후 출력해준다
MOV DX, msgs[6] ; 저장된 문자열을 출력한다
MOV AH, 09
INT 21H
MOV DX, '0' ; 16진수 표기를 위해 0x를 먼저 출력해준다
MOV AH, 2
INT 21H
MOV DX, 'x'
MOV AH, 2
INT 21H
MOV CX, 4 ; 4바이트이므로 4번 반복하여 출력한다
PRINT:
POP DX ; 저장된 값을 dx로 pop한다
ADD DX, '0' ; 문자 0만큼 더해주어 문자로 출력되게 한다
MOV AH, 2
INT 21h
LOOP print
MOV AH, 4CH ; 프로그램 종료 인터럽트
INT 21H
MAIN SEGMENT
ASSUME CS:MAIN, DS:MAIN
MOV AX, CS
MOV DS, AX
MOV BX, 0
INPUT:
MOV DX, msgs[BX]
MOV AH, 9
INT 21H
MOV DX, OFFSET max_len
MOV AH, 0AH
INT 21H
MOV CX, OFFSET str1
ADD CL, act_len
ADC CH, 0
MOV DX, OFFSET CRLF
MOV AH, 9
INT 21H
MOV SI, OFFSET str1
ADD SI, 4
MOV CX, 1
CAST:
MOV AX, 0
MOV AL, [SI]
CMP AL, '0'
MUL CX
ADC array[BX], AX
MOV AX, CX
MOV CX, 10
MUL CX
MOV CX, AX
PASS:
DEC SI
CMP SI, OFFSET str1
JB CAST_END
JMP CAST
CAST_END:
ADD BX, 2
CMP BX, 6
JE INPUT_END
JMP INPUT
INPUT_END:
MOV BX, array[0]
CMP BX, array[2]
COMP:
CMP BX, array[4]
MOV CX, 4
JAE HEX
MOV BX, array[4]
HEX:
MOV AX, BX
SHR BX, 1
SHR BX, 1
SHR BX, 1
SHR BX, 1
AND AX, 0FH
CMP AX, 0AH
JL SAVE
ADD AX, 7
SAVE:
PUSH AX
LOOP HEX
MOV DX, msgs[6]
MOV AH, 9
INT 21H
MOV DX, '0'
MOV AH, 2
INT 21H
MOV DX, 'x'
MOV AH, 2
INT 21H
MOV CX, 4
PRINT:
POP DX
ADD DX, '0'
MOV AH, 2
INT 21H
LOOP PRINT
MOV AH, 4CH
INT 21H
CRLF DB 0AH, 0DH, "$"
msg1 DB "First Number: ", "$"
msg2 DB "Second Number: ", "$"
msg3 DB "Third Number: ", "$"
msg4 DB "Largest Number: ", "$"
msgs DW OFFSET msg1, OFFSET msg2, OFFSET msg3, OFFSET msg4
max_len DB 6
act_len DB ?
str1 DB 6 dup(0)
array DW 0, 0, 0
MAIN ENDS
END