Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

번역 : 강웅빈 감수 : 프갤ㅤ횽들

14 정수의 곱셈 나눗셈과 산술이동 명령

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_1.html

이 장에서는 32비트 정수 곱샘을 수행하는 mips명령을 공부한다. 정수를 비트배턴으로 표현하는 주제는 이미 다루었고 복습이다.

장의 주제:

  • 정수 곱셈과 나눗셈.
  • hi와 lo 레지스터.
  • mult와 multu 명령.
  • div와 divu 명령.
  • mfhi와 mflo 명령.
  • 오른쪽 산술 이동 (Arithmetic shift right).
  • sra 명령.

질문:

99<10> 과 99<10> 곱하라 : _________

각 피연산자 99를 표현하기 위해 몇개의 십진수 자리가 필요 합니까?: ________

곱셈의 결과를 표현하기 위해서는 몇개의 십진수 자리가 필요합니까?: ________

2배가 되는 자릿수

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_2.html

답:

99<10> 과 99<10> 곱하라 : 9801<10>

각각의 피연산자 99를 표현하기 위해 몇개의 십진수 자리가 필요 합니까?: 2

곱셈의 결과를 표현하기 위해서는 몇개의 십진수 자리가 필요합니까?: 4

두N자리 십진수 정수의 곱을 표현하기위해는 최대 2N자리가 필요하다. 이 문장은 진수에 관계없이 참이다. 예를들면 N비트의 2진수정수의 곱을 표현하기 위해서는 최대 2N비트가 필요하다. 여기에 부호없는 두 8비트 정수의 곱을 종이와 연필을 쓰는 방법으로 표현해보았다. (물론 2진수 연산을 사용한다.)
        10110111            B7          183<10>
        10100010            A2          162<10>
        --------            --          ---
        00000000
       10110111.
      00000000..
     00000000...
    00000000....
   10110111.....
  00000000......
 10110111.......
 ---------------          ----        -----
 111001111001110          73CE        29646<10>}}}

두 8비트의 피연산자는 15비트의 결과를 보여준다. 같은 연산을 10진수 그리고 16진수로도 해보았다.

질문 :
일반적으로 32비트의 일반 레지스터가 두개의 32비트정수를 피연산자로 가지는 곱셈연산의 결과를 올바르게 보관할 수 있겠습니까?

=== MIPS 곱셈 유닛(multiply unit) ===
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_3.html

답: 올바르게 보관 할 수 없습니다. 일반적으로 64 bits이 필요합니다.

MIPS의 곱셈유닛은 각각 hi와 lo라고 불리는 2개의 32비트 레지스터를 담고 있다. 이 레지스터들은 범용레지스터(general-purpose register)가 아니다. 2개의 32비트 크기의 피연산자가 곱셈되어질 때, hi와 lo 레지스터는 64 bits 크기의 결과물을 담고있다. 32번 비트부터 63번 비트까지는 hi 레지스터에있고 0번부터 31번까지 비트는 lo 레지스터에 있다.
 
attachment:HiLoMult.gif

다음의 명령을 살펴보자. 피연산자들은 범용레지스터에 담겨져있다.


mult    s,t        # hilo <-- $s * $t.  2의 보수표현 피연산자들

multu   s,t        # hilo <-- $s * $t.  부호구분하지 않는 피연산자들(unsigned operands)

부호구분을 하지 않는 곱셈명령과 2의 보수법으로 표현되어 부호를 구분하는 곱셈명령이 있다. 정수 곱셈(interger muliplication)에서는 트랩(trap)이 발생하지 않는다.

주목할점: add와 addu 명령의 경우 두 명령이 같은 작동(operation)을 실행 했다. 덧셈명령에서 "u"는 오버플로우시 트랩(trap)을 발생시키지 않는다는 의미였다. mult와 multu의 경우는 각기 다른 작동(operation)을 실행한다. 두 곱셈명령다 트랩(trap)을 발생시키지는 않는다.

질문: 두개의 작은 크기의 정수를 곱셈하였습니다. 결과는 어디에 있겠습니까?

유효비트(Significant bits)

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_4.html

답: 만약 결과가 lo에 다 들어갈 만큼 작다면, hi는 0이 됩니다.. 우리가 작성할 대부분의 프로그램의 결과는 32비트를 넘지 않고, 만약 32비트를 넘지 않는 수 라면 곱셈의 결과는 lo에 저장됩니다.

양수 혹은 부호 없는 수의 유효비트는 가장 왼쪽에 있는(the most significant) 1을 포함해서 그 오른쪽에 있는 모든 비트를 의미한다. 예를 들어 다음은 23개의 유효비트를 가지고 있다.
0000 0000 0100 0011 0101 0110 1101 1110}}}
음수의 '''유효비트'''는 가장 왼쪽에 있는(the most significant) 0을 포함해서 그 오른쪽에 있는 모든 비트이다. 예를들어 다음은 23개의 유효비트를 가지고 있다.dd

1111 1111 1011 1100 1010 1001 0010 0010}}}
두 수의 곱의 유효비트의 갯수가 32개가 넘지 않게 하기 위해서 각 피연산자의 유효비트또한 32개 이하 여야 한다. 지금 이 코스에서는 이것에 대해 걱정할 필요는 없다.

질문:
아래의 곱셈의 결과의 유효비트의 갯수가 몇 개나 되겠습니까?

01001010 × 00010101}}}

=== mfhi 와 mflo 명령 ===

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_5.html

답:
12개 이하

곱셈의 결과를 일반 레지스터로 옮기기 위해 사용하는 두 가지 명령이 있다.

mfhi    d        #  d <-- hi.  Hi로부터 이동(move from hi)
mflo    d        #  d <-- lo.  Lo로부터 이동(move from lo)}}}
hi와 lo레지스터는 다른 산술 명령이나 논리 명령과 함께 사용될 수 없다. 만약 곱셈의 결과를 사용하고자 한다면 먼저 일반 레지스터에 복사에 사용해야한다. 더군다나 MIPS하드웨어상의 이유로 인해 좀 더 복잡한 규칙이 있다.

'''규칙''': mflo나 mfhi명령 후 2명령동안 어떠한 곱셈 혹은 나눗셈 명령을 사용하면 안된다. 이것은 MIPS의 파이프라인의 작동방식에 일부 기인한다. SPIM시뮬레이터에서 이 규칙은 적용되지 않는다.

질문:
두 곱셈 명령을 하고 싶습니다. 2번째 곱셈을 하기전에 꼭 lo 와 hi에서 결과를 옮겨야 합니까?

=== 예제 프로그램 ===

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_6.html

답: 예.

x값이 $8에 있는 식 5 × x - 74 의 값을 계산하는 프로그램을 만들었다. x는 2의 보수표현식으로 쓰여진 정수라고 가정한다.

## newMult.asm
## 
## 5 × x - 74 를 계산하는 프로그램
##
## 사용되는 레지스터:
##  $8   x
##  $9   결과

        .text
        .globl  main

main:
        ori      $8,   $0, 12         # x -> $8
        ori      $___, $0,  5         # 5 -> $___
        mult     $___, $___           #  ___ × 5x
        mflo     $___                 # $___ = 5x
        addiu    $___, $___,-74       # $___ = 5x - 74

## End of file}}}

질문: 빈칸을 채워보십시오. 이 프로그램을 텍스트 에디터로 옮겨서 바꾸는 것이 좋을 것입니다. 파일을 저장한 뒤 프로그램을 SPIM에서 실행해서 결과를 확인해 보십시오. 

=== 예제 프로그램2 ===
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_7.html


다음은 빈칸을 채운 완전한 프로그램이다. 이 프로그램에서는 단지 하나의 부수적인 레지스터가 필요했다. 레지스터 9에 여러단계의 결과를 저장하였다. 


## newMult.asm
## 
## 5 × x - 74 를 계산하는 프로그램
##
##사용되는 레지스터:
##  $8   x
##  $9   결과

        .text
        .globl  main

main:
        ori      $8, $0, 12       # x -> $8
        ori      $9, $0,  5       #  5 -> $9
        mult     $9, $8           # lo <-- 5x
        mflo     $9               # $9 = 5x
        addiu    $9, $9,-74       # $9 = 5x - 74

## End of file

질문:

다음의 각 명령에서 "u"는 무었을 의미합니까?

  • addu ____________________
  • multu____________________

프로그램 실행

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_8.html

답:

  • addu 오퍼플로우시 트랩을 발생시키지 않는다.
  • multu 계산시 피연산자들의 음수양수부호를 고려하지 않는다(unsinged).
mult 명령은 피연산자가 2의 보수로 표현되었다고 가정한다. 프로그램의 카운터(PC)는 0x400000에서 초기화 되서 실행된다. F10(한 스텝 명령)을 다섯번 눌러보자. 다음은 실행한 프로그램의 마지막 결과를 보여주는 그림이다.

attachment:newMultRun.gif

다음과 같은 결과를 볼 수 있다.

5 × 12 - 74 = -14 = 0xFFFFFFF2

곱셈의 결과(product)는 5 × 12 = 60<10> = 0x3C 이고 lo 레지스터에 결과는 남아있다.

질문:

몫과 나머지를 계산하는 다음 십진수 정수 나눗셈을 해보자.

  • 99 / 2 = _____ R ____
  • 99 / 50 = _____ R ____

div와 divu 명령

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_9.html

답:

99 / 2 = 49 R 1 99 / 50 = 1 R 49

N자리 정수가 나눠지면 N자리 몫과 N자리 나머지, 즉 2가지 결과가 나온다. 32비트 피연산자를 나누었을때 (보통은) 두개의 32비트의 결과가 나온다. MIPS는 결과를 hi와 lo레지스터에 저장한다. attachment:HiLoDivkor.GIF 정수나눗셈을 위한 MIPS명령이다. u는 결과와 피연산자가 부호없는 정수라는 것을 의미한다
div    s,t        #  lo <-- s / t
                  #  hi <-- s mod t
                  #  2의 보수식 표현
divu   s,t        #  lo <-- s / t
                  #  hi <-- s mod t
                  #  부호없는 정수

질문: 몫을 레지스터 $8로 옮기기 위해 어떤 명령을 사용합니까?

예제 프로그램3

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_10.html

답: mflo $8

mflo 와 mfhi는 정수 나눗셈의 결과를 구하기 위해 쓰입니다.

또 다른 예제이다: (y + x)/(y - x) 를 구하고 싶다고 하자. x는 $8에 있고 y는 $9 에 있다. 몫은 $10에 그리고 나머지는 $11에 있어야 한다. 정수는 2의 보수표현식으로 표현 되었다고 가정한다. 예제프로그램이다. 안타깝게도, 빈칸을 채워 넣어야한다.

## divEg.asm
## 
## (y + x) / (y - x)를 계산하기위한 프로그램
##
## 사용되는 레지스터
##  $8   x
##  $9   y
##  $10  x/y
##  $11  x%y

        .text
        .globl  main

main:
        ___      $8,   $0,  8         # x -> $8
        ___      $9,   $0, 36         # y -> $9
        addu     $10,  $__, $__       # $10  <-- (y+x)
        subu     $11,  $__, $__       # $11  <-- (y-x)
        div      $__,  $__            # hilo <-- (y+x)/(y-x)
        ____     $10                  # $10  <-- 몫
        ____     $11                  # $11  <-- 나머지

## 파일의 끝}}}

질문:  
빈칸을 채워보자

=== 예제의 답 ===

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_11.html

답: 아래에 있습니다.

## divEg.asm
## 
## (y + x) / (y - x)를 계산하기위한 프로그램
##
## 사용되는 레지스터
##  $8   x
##  $9   y
##  $10  x/y
##  $11  x%y

        .text
        .globl  main

main:
        ori      $8,   $0,  8         # x -> $8
        ori      $9,   $0, 36         # y -> $9
        addu     $10,  $9, $8       # $10  <-- (y+x)
        subu     $11,  $9, $8       # $11  <-- (y-x)
        div      $10,  $11            # hilo <-- (y+x)/(y-x)
        mflo     $10                  # $10  <-- 몫
        mfhi     $11                  # $11  <-- 나머지

## 파일의 끝}}}

질문: (36+8) / (36-8) = ?? 나머지 ??


=== 프로그램 실행 ===

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_12.html

답 : (36+8) / (36-8) = 1 나머지 16, 또는 0x1 나머지 0x10 

실행 결과이다.
attachment:divEgRun.gif

평소와 같이 완벽한 결과를 볼 수 있다.

질문: 
-16을 2의 보수 표현식으로 표현하면 다음과 같습니다:

1111 1111 1111 0000}}}
2자리만큼 논리적 오른쪽 쉬프트 해보십시오. 결과가 -16/4와 같습니까?

=== 산술적 오른쪽 쉬프트(Shift Right Arithmetic) ===
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_13.html

답: 

1111 1111 1111 0000  ---> 0011 1111 1111 1100}}}

아니오. 결과는 -4가 아닌 아주 큰 양의 정수입니다. 

논리적 오른쪽 쉬프트를 2의 보수식으로 표현된 음의 정수에 사용하면 2로 나눈 결과와는 다르다. 문제는 논리적 오른쪽 쉬프트가 0을 상위 비트에 집어넣기 때문이다. 이것은 양의 정수 나눗셈에서는 올바르지만 음의 정수의 나눗셈에서는 올바르지 못한 결과를 가져온다. 산술적 오른쪽 쉬프트는 필요한만큼 부호비트를 상위비트들에 붙여넣는다.

attachment:arithRightKor.GIF

질문:

산술적 왼쪽 쉬프트(Arithmetic shift left)가 필요 합니까?

=== SRA 명령 ===
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_14.html

답: 필요없습니다. 산술적 왼쪽 쉬프트는 낮은 비트에 0을 이동시킬 뿐입니다. 부호에 상관없이 정확한 결과를 산출합니다.

MIPS는 산술적 오른쪽 쉬프트 명령(shift right arithmetic instruction)을 가지고 있다.


sra    d,s,shft   #  s레지스터를 shft만큼 이동하여 d레지스터에 저장한다.
                  #  shft는 이동하는 크기
                  #  0 =< shft < 31 의 크기이다.

때때로 2로 나눗셈을 할필요가 있다. 그런 경우 sra명령은 div명령을 사용하는 것 보다 빠르고 편리하다.

질문: sra명령은 부호가 없는 정수의 경우에도 정확한 결과를 산출합니까?

14장 끝

http://chortle.ccsu.edu/AssemblyTutorial/Chapter-14/ass14_15.html

답: 아니오, 부호 없는 정수에서는 '부호비트'가 복제되서는 안됩니다.

논의된 주제

  • 정수 곱셈의 결과의 자릿수
  • 정수 나눗셈의 결과의 자릿수
  • hi와 lo레지스터
  • mult와 multu명령
  • mfhi와 mflo명령
  • div와 divu명령
  • 산술적 오른쪽 쉬프트 명령
  • sra명령
퀴즈 프로그램과제를 해봅시다.

수다

  1. 자바하는놈 공부좀 쉬엄쉬엄하니까 또 마음이 흔들립니다. 한말씀 감사. 이것참 옆에서 누가 공부하란사람덜도 없고.
  2. 자바하는넘 얼마 안남았잖어 조금만 더푸쉬해.. 공부는 해보면 집중인거 같에.. 10분을 보더라도 집중해서 할 수 있으면 좋지... 공부잘하는 사람들은 그걸 장시간 동안할 수 있는 사람들이고... 우ㅤㅉㅐㅎ든 화이팅
  3. javaseki the monitor what i'm watching at now is ridiculous, its resolution seems like 800x600, i cant even see whole page at once.. lol
  4. 자바하는놈 형, 포트폴리오같은거 어떻게 만드는지 나와있는 페이지같은거 가지고 계세요? 구글링도 안돼고 지식즐도 모르고.. -_-
  5. 자바하는놈 그리구..그 화학 어플리케이션 아주 잘쓰고있어용.. 워드로 OLE(오래전에 들어서 용어가 맞는지.. object linking embedding..이었나.. 한국서 고등학교에서 배울땐 뭔소린지도 모르고 그랬는데..ㅎㅎ)돼고 아 아주 좋아요.. ㄳ
  1. 자바하는넘 글쎄 그게 학교에서 개발방법론 배울때 할 지 모르는데 스펙만들고 아키텍춰설명하고 그게 딱 abc식으로 정해진것 은 없어서... 오픈소스중에서 작으면서도 활발한 프로젝트보면 사이트도 잘만들어 놓았고 생각도 명확하게 제시하는데 그런거 참조해 보지... apache mina한국분이 주참여자인가보던데 그런 사이트 보면서 어떻게 자기가 생각하는 걸 정리하고 설명하고 구현했는지를 보여주면 좋은가 ^^
프로젝트가 무슨 문제를 해결해주는가? 왜 이런식으로 구현했는가? 장점과 단점? 유지보수는 어떻게 할것인가 그런생각들을 가지고 정리해서 남한테 의견 제시할 수 잇으면 좋은 포트폴리오라고 할 수 있나.. 나도 함 찾아보지. 열공.
  1. 자바하는놈 ㄳ.. 질문의 나머지반은.. 대입大入용.. -_-이었슴다.. 넴 열공...하려고 노력중. 주말에 책한권 맘잡고 끝냈지 말입니다. 열공후 스타한판이 최고.. 열공안하고 하면 찜찜하져~