코드보기: 나눗셈

나눗셈

    .PROCESSOR 6502
    .ORG $8000
 
num=$20
denom=$21
res=$22
    ldx #$FF
    txs
 
    ; == DEFINE OPERANDS HERE ===
    lda #45
    sta num
 
    lda #3
    sta denom
    ; ===========================
 
    ldx #0  ; X = solution
 
    sec
    lda num
    sbc denom
 
loop:
    bmi end
    inx
    sbc denom
    jmp loop
 
end:
    stx res
 
    .ORG $FFFC,0
    .WORD $8000
    .WORD $0000

나눗셈은 반복문이 필요하다.

ldx #0

X 레지스터 에 몫을 저장한다.

  • 반복 횟수가 곧 몫이다.
  • 나눗셈은 뺄셈의 반복

루프 전에 미리 sbc를 1회 수행한다.

위에서 sbc를 1번 수행했기 때문에 바로 bmi로 음수인지 확인해 분기할 수 있다.

복습 퀴즈

6502 어셈블리어에서 반복문이란 무엇인가요?

비교와 조건부 점프 명령어의 조합

6502 어셈블리어에서 역방향 반복문(카운터를 감소시키는 것)이 더 빠른 이유는 무엇인가요?

  1. 명령어가 적게 필요하기 때문에

    • 맞는 말이긴 한데, 더 맞는 말이 2번이라서 오답
  2. 감소 명령어가 제로 플래그를 설정하여 추가 비교가 필요 없기 때문에

    • dex 때문에 cpx가 필요없음
    • 정답
  3. 프로그램 카운터를 직접 수정하기 때문에

    • 이건 jmp 인데..?
    • 오답
  4. 페이지 크로싱을 피하기 때문에

    • 관계 없다.
    • 오답

6502 어셈블리어에서 반복문에 대한 다음 설명 중 올바른 것은 무엇인가요?

  1. 반복문 코드는 그렇지 않은 경우보다 바이트 수를 적게 사용한다.
  • 항상 그런 것은 아니다.
; 반복문 없이 (unrolled)
LDA $C000    ; 3바이트
STA $2000    ; 3바이트
LDA $C001    ; 3바이트
STA $2001    ; 3바이트
; 총: 12바이트
 
; 반복문 사용
LDX #0       ; 2바이트
loop:
  LDA $C000,X ; 3바이트
  STA $2000,X ; 3바이트
  INX          ; 1바이트
  CPX #2       ; 2바이트
  BNE loop     ; 2바이트
; 총: 13바이트  ← 오히려 더 큼!
  1. 반복문 코드는 그렇지 않은 경우보다 실행 속도가 빠르다.

    • 분기, 비교 오버헤드가 있기 때문에 보통 더 느리다.
  2. 루프 명령어는 메모리 주소를 자동으로 증가한다.

    • 이런 명령어는 없다.
  3. 실행 도중에 반복 횟수가 정해지는 경우에 사용하기 적합하다.

    • 정답
    • 런타임에 반복 횟수가 정해지는 경우 필수다. 다른 방법은 없다.
    • 컴파일 타임에 반복 횟수가 정해진 경우 하드 코딩 가능

직접 짠 몫과 나머지를 구하는 코드

num=$10  
divisor=$11  
quotient=$12  
remainder=$13  
  
; stack 초기화  
    ldx #$FF  
    txs  
  
    ldx #0  
    lda num  
    sec  
  
.divide  
    sbc divisor  
    bmi .recover      ; 음수면 이전값 복구  
    inx  
    bne .divide  
  
.recover  
    clc    
    adc divisor       ; 음수값에 divisor를 더해서 원래값(나머지) 복구  
  
.output  
    sta remainder  
    stx quotient