.286 ; 286명령어를 사용할수 있게 한다.
SSEG SEGMENT STACK ; EXE파일을 만들 것이므로 스택설정한다.
DB 256 DUP(?)
SSEG ENDS
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DSEG SEGMENT
BUFFER DB ?, " * ", ?, " = ", ?, ?, 0DH, 0AH, '$'
DIVNUM DB 10 ; 결과값이 10을 넘을 경우 두부분으로 나누기 위해 10을 넣는다.
DSEG ENDS ; 데이터 세그먼트 영역.
; 화면에 출력할 포맷임.
; 하지만 문제는 세번째 ?부분은 ?, ?가 되어야 한다.
; 연산결과는 십진수로 2자리이고 바이트 1개 자리로 표현 되는
; 숫자문자는 0부터 9까지만이므로 한자리가 더 필요하다.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG, SS:SSEG, DS:DSEG
MAIN PROC FAR
PUSH DS ; 프로그램을 정상적으로 종료시키기 위해 스택에 리턴할 주소를 넣는다.
PUSH 0 ; 먼저 PSP(Program Segment Prefix) 세그먼트 주소를 스택에 넣고 리턴할 옵셋인 0을 넣는다.
; 이렇게 하면 프로그램 종료를 위해 아래 RETF명령을 사용하면
; PSP맨 앞에 있는 CD 20(INT 20h)를 실행하여 프로그램을 종료하게 된다.
MOV AX, DSEG ; 데이터 세그먼트로 설정된 DSEG의 세그먼트 주소를 DS에 넣는다.
MOV DS, AX
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MOV BH, 5 ; 출력하고자 하는 단수. 여기에 원하는 단수를 넣으면 된다.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MOV CX, 9 ; 루프 반복 횟수
MOV BL, 0 ; 곱해지는 수 초기화(1,...,9)
L1:
ADD BL, 1 ; BL값에 1씩 더한다. BL은 루프안에서 1부터 9까지 된다.
; 간단하게 INC BL해도 된다.
MOV AL, BL ; BL값을 AL로 복사한다.
MUL BH ; AX = BH(단수) * AL(각 단 내에서 곱해지는수)
; 결과는 AX로 얻어진다.
MOV BUFFER, BH ; (1) * (2) = (3) 에서 (1)부분 세팅
ADD BUFFER, '0' ; 화면에 출력할 단수값을 데이터 세그먼트안의 BUFFER에 저장하고 30H('0')를 더한다.
MOV BUFFER+4, BL ; (1) * (2) = (3) 에서 (2)부분 세팅
ADD BUFFER+4, '0' ; 화면에 출력할 곱해지는 수를 데이터 세그먼트 안의
; BUFFER에서 4번째(위에서 두번째 ?)에 저장하고 30H('0')를 더한다.
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; ADD AL, '0' ; (1) * (2) = (3) 에서 (3)부분 세팅
; MOV BUFFER+8, AL ; 얻어진 연산결과에 30H('0')를 더한후 BUFFER에서 8번째(위에서 세번째?)에 저장한다.
;
; 위 코드는 잘못되었다. AL(AX)에 있는 값은 0부터 9까지의 수만이 아니기 때문이다.
; 그렇기 때문에 이것을 화면에 출력하려면 두 부분으로 나누어야 한다.
; 결과값을 10으로 나눈 나머지와 몫을 별도로 출력해야 한다.
CMP AL, 10 ; 10보다 작으면 그냥 출력.
JL L2
; 10이상인경우
DIV DIVNUM ; 10이상이면 10으로 나눈다음.
MOV BUFFER+8, AL ; AL에 있는 몫을 저장한다음.
ADD BUFFER+8, '0' ; 30H를 더해 숫자문자로 변환.
MOV BUFFER+9, AH ; AH에 있는 나머지 부분을 저장한다음.
ADD BUFFER+9, '0' ; 30H를 더해 숫자문자로 변환한다.
JMP short L3
L2:
MOV BUFFER+8, ' ' ; 10미만이면 앞에는 공백문자를 넣고 뒤에 결과값을
MOV BUFFER+9, AL ; 넣고 30H를 더해 숫자문자화시킨다.
ADD BUFFER+9, '0'
L3:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MOV AH, 09H ; 위 과정에 의해 세팅된 문자열을 화면에 출력
LEA DX, BUFFER
INT 21H
LOOP L1 ; CX만큼 반복한다.
RET ; RET명령을 썻지만 어셈블하면 RETF명령에 해당되는 코드로 변환된다.
; 이 명령을 사용하여 PSP:0000에 있는 CD 20을 실행하는 곳으로 간다.
MAIN ENDP
CSEG ENDS
END MAIN
'IT > Assembler' 카테고리의 다른 글
1부터 5까지의 합 (0) | 2014.12.19 |
---|---|
[ASM]구구단중 2단의 결과값 구하는 예제소스 (0) | 2014.12.19 |
[ASM]구구단 1단 출력 (0) | 2014.12.19 |
[어셈블러] LOOP을 이용한 1부터 10까지 더하기 (0) | 2014.12.19 |
어셈블리어 기본 (0) | 2014.12.19 |