본문 바로가기
어셈블리어 공부용/x86 어셈블리어(ASSEMBLY)

emu8086으로 어셈블리어 연습 [ROL 명령어로 2의 거듭제곱 단위로 수 나열하기]

by Redoutable 2019. 8. 18.
반응형
.MODEL SMALL
.CODE
ORG 100h

PROG:
    CALL MAIN
    
MAIN PROC NEAR
    MOV CL, 1  ; 비트를 왼쪽으로 1만큼 이동시키기 위해서 CL에 1을 넣습니다.
    MOV AL,1   ; AL레지스터에 1을 넣어줍니다.
    
ROLAL:       
    ROL AX,CL  ; AX 레지스터에 있는 비트들을 왼쪽으로 한 칸 움직입니다. 한 칸씩 움직일 때마다 2배씩 수가 증가합니다.
    PUSH CX    ; 데이터를 스택에 저장.
    PUSH AX    ; 데이터를 스택에 저장.
    
    MOV CX,0   ; 진수변환 앞서서 CX레지스터 청소
DECA:
    MOV DX,0   ; 진수변환 앞서서 DX레지스터 청소     
    MOV BL,10  ; 10을 곱해주기 위하여 BL에 10 입력.
    DIV BX     ; AX 레지스터를 10으로 나눎.
    
    PUSH DX    ; 나눗셈 결과로 나오는 나머지들을 스택에 수록.
    
    INC CX     ; CX레지스터를 1씩 증가시켜둠.
    CMP AL,0   ; AL레지스터(몫)가 0인지 아닌지 확인.
    JNE DECA   ; 몫이 0이 아니라면 진수변환 계속하기위하여 DECA로 이동.
    
DISP:
    POP DX     ; 나머지들을 역순으로 꺼내옴. (스택은 선입 후출이라는 특성을 가지고있음.)
    ADD DL,30h ; 30h를 더하여 아스키코드화 시킴.
    MOV AH,02  ; 문자 하나를 출력해야 하니까 AH레지스터에 기능번호 2번 수록.
    INT 21h    ; 실행
    
    DEC CX     ; 위에서 증가시켜뒀던 CX레지스터 값 사용함. 진수변환 횟수만큼 출력을 실행. 
    CMP CX,0   ; 수가 0인지 아닌지 확인. (출력이 끝났는지?)
    JNZ DISP   ; 아니라면 DISP로 보내어 출력을 계속진행.
    
    MOV DL,' ' ; " "(공백)을 DL레지스터에 수록 (공백은 아스키코드로 20h번. 20h를 대신 입력해도 된다.)
    INT 21h    ; 공백을 출력하여 출력한 수가 구분이 쉽도록 한다.
    MOV AX,0   ; 출력과정이 끝났으면 AX레지스터를 청소.
    
    POP AX     ; 보존해뒀던 AX값 AX로 출력
    POP CX     ; 보존해뒀던 CX값 CX로 출력
               ; (스택에 CX AX 순으로 저장했다면 출력은 AX CX순으로 해야 오류가 생기지 않는다. 먼저들어간게나중에.
    
    CMP AX,32768 ; AX레지스터값 = 32768 ?
    JNZ ROLAL    ; 아니라면 ROLAL로 보내어 비트를 왼쪽으로 움직여(ROL) AX레지스터의값을 X2시킴. 출력계속해서진행.

     
MAIN ENDP
END

 

 

 

ROL 명령어로 비트를 왼쪽으로 한 칸씩 움직여서 2의 거듭제곱 단위를 출력하는 프로그램입니다.

16비트는 65536까지 표현이 가능하지만,비트를 한 칸씩만 왼쪽으로 움직여야 한다고 치면,

최상위비트(MSB, most significant bit)에 1이 수록됐을때 그 값이 32768 이기때문에

이것을 초과하는 수를 표현하지는 못합니다.

반응형

댓글