13장 덧셈 명령과 뺄셈 명령(Addition and Subtraction Instructions)
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_1.html
이 장에서는 32비트 정수 덧셈과 뺄셈을 위한 명령에 대해 다룬다. 비트패턴으로 정수를 표현하는 방법도 복습 할 것이다.
이 장에서는 다음과 같은 주제를 다룬다.
부호없는 2진수와 2의 보수 표현법에서의 오버플로우(Overflow in unsigned binary and two's complement)-복습
add와 addu명령
사인 연장하기(Sign extension)
addi 와 addu 명령
sub과 subu명령
addi를 사용해 레지스터에서 음수 로드하기
질문:
프로세서가 완벽한 비트단위 조작연산을 지원한다고 합시다. 이것으로 산술적 명령을 수행 할 수 있겠습니까?
비트단위 조작 연산으로서의 산술연산
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_2.html
답: 예(부동소숫점 연산도 마찬가지 입니다)
정수들은 비트패턴으로 표현되어 있기 때문에, 정수연산이란 곧 비트들을조작하는 연산이다. 몇몇의 작고 빠른 프로세서들은 아예 비트조작연산만 지원하는 경우가 있다. 그러한 경우에는 정수를 2개 더하는 덧셈연산은 8장에서 본 것 같은 바이너리 덧셈 알고리듬(8장)을 비트 조작 명령을 사용하여 구현된다.
운좋게도, MIPS는 정수 산술연산명령을 가지고 있다. 일반적인 정수의 크기는 32비트이다(레지스터의 크기와 같다). 좀더 크거나 작은 정수를 위한 산술연산은 32비트 산술연산과 비트단위 조작연산을 조합해서 할 수 있다.
질문: MIPS의 addu연산은 두 32비트 패턴에 대해 바이너리 덧셈 알고리듬을 사용합니다. 이 방법과 같이 사용될 수 있는 정수 표현법은 무엇입니까?
*부호없는 이진수
*2의 보수 표현법
*둘다
바이너리 덧셈 알고리듬(Binary Addition Algorithm)
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_3.html
답:둘다
바이너리 덧셈 알고리듬은 위의 두가지 정수표현방식에도 모두 동작한다. MIPS에서도 한가지 명령(addu)이 두 표현방식에 다 쓰인다. 그러나 오버플로우조건은 각각 다르다.
바이너리 덧셈 알고리듬: 오버플로우조건
부호없는정수
2의 보수
가장 왼쪽에 있는 캐리아웃이 0이면 결과가 옳다
캐리인과 캐리 아웃값이 같을때 결과가 옳다. 옳은 경우 캐리 비트는 캐리인과 캐리아웃 모두 0일 수도 있고 또는 모두 1일 수도 있다.
부호없는 정수의 경우 : 오버플로우. 캐리아웃이 1입니다.
2의 보수의 경우 : 오버플로우아님. 캐리인과 캐리아웃이 동일
addu 명령은 두개의 32비트 레지스터에 대해 바이너리 덧셈 알고리듬을 수행한 후 그 결과를 결과 레지스터(destination register)에 저장한다. 결과 레지스터와 소스 레지스터가 같아도 상관 없다. addu명령은 기계적으로 바이너리 덧셈 알고리듬을 적용해 결과를 얻은 후 32비트의 결과 레지스터에 저장한다. 오버플로우는 무시된다. (addu끝의 u가 그러한 뜻이다. unchecked :역주)
add라는 명령도 있다. addu와 유일하게 다른 점은 2의 보수식의 정수를 연산할때에 오버플로우가 발생하면 트랩(trap)을 발생시킨다는 것 이다. 트랩은 정상적인 기계 주기(normal machine cycle)의 중단을 의미한다. 보통의 컴퓨터 시스템에서 트랩은 운영체제로 제어를 넘긴다.
대부분의 어셈블리 프로그래머들은 오버플로우 방지를 위해 미리 피연산자를 점검한다. 그래서 어셈블리 프로그래머들은 보통 addu명령을 사용한다. 트랩의 사용방법을 배우기 전까지 우리는 addu를 사용할 것이고 같은 방법으로 오버플로우를 방지 할 것이다.
질문:
2의 보수식으로 정수를 표현할 때 32비트로 표현 가능한 정수의 범위가 어떻게 됩니까(x,y)?
-2^x to +2^y-1
(^는 지수승)
예제 프로그램
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_5.html
답: x, y모두 31. 반은 음의 정수, 나머지는 영과 양의 정수에 쓰입니다.
이전에 나왔던 덧셈문제를 32비트로 확장해 보았다.
이진수
16진수
캐리값
0000 0000 0000 0000 0000 0001 1111 111
0000 0000 0000 0000 0000 0000 1010 1011
000000AB
+
0000 0000 0000 0000 0000 0000 0101 0101
00000055
0000 0000 0000 0000 0000 0001 0000 0000
00000100
부호없는 8비트의 부호없는 연산(unsigned arithmetic)에서는 오버플로우가 났으나 32비트에서는 범위안에 있다.
## AddSome.asm
##
## 덧셈 시연용 프로그램
.text
.globl main
main:
ori $8, $0, 0xAB # 0x000000AB를 $8에 집어넣는다
ori $9, $0, 0x55 # 0x00000055를 $9에 집어넣는다
addu $10,$9, $8 # 합은 $10에 넣는다
## 파일의 끝
질문: 이 프로그램에서 $8과 $9의 내용이 바뀝니까?
프로그램 실행
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_6.html
답:
안바뀝니다. 피연산자의 레지스터가 저장되는 레지스터가 아니기 때문에 피연산자 레지스터의 내용은 변하지 않습니다.
다음 그림은 프로그램을 실행한 것이다. 결과는 예상했던대로 나타난다. 소스코드를 text 영역(그림에서 아래쪽 창) 오른쪽에서 볼 수 있다. text 영역 중간의 행에서 명령의 직접피연산자가 십진수로 표현된것을 볼 수 있다.
attachment:addSome.gif
직접 연산자를 십진수로 표현하기 위해서는 앞에 붙이는 0x를 생략하자.
ori $8, $0, 171 # 171을 8번 레지스터에 저장
ori $9, $0, 85 # 85를 9번 레지스터에 저장
addu $10,$9, $8 # $9번 $8번을 더한 값을 10번에 저장
물론, 기계명령에서 직접피연산자는 16비트 크기의 패턴이다. 어셈블러는 여러분이 16진수 명명법이나 10진수 명명법을 사용하여 지정한 패턴을 16비트 크기의 패턴으로 전환시킨다.
질문: (복습)음수인 상수(negative const)를 다음 명령에 사용할 수 있을까요?
ori $d,$0,const
2의 보수식의 값을 음수로 바꾸기
http://chortle.ccsu.edu/AssemblyTutorial/Chapter-13/ass13_7.html
답: 안됩니다. 상수(const)가 저장되는 레지스터 d로 복사될 때 16비트의 직접 피연산자는 0을 사용하여 32비트로 확장됩니다. 그러므로 음의 정수가 될 수 없습니다.
흥미로운 비트조작 문제를 준비했다. 레지스터에 이미 불러들인 정수를 음의 정수로 바꾸고 싶다고 하자. (나중에는 좀 더 쉬운 방법을 알려 줄 것이다) 여지껏 배운 연산으로 시도해보자.
2의 보수식의 정수를 음수로 만드려면 비트의 0과 1을 바꾼 후 1을 더하면 된다는 것을 기억하자.
문제: 레지스터 $8에 양의 정수 82를
Contents
13장 덧셈 명령과 뺄셈 명령(Addition and Subtraction Instructions)
비트단위 조작 연산으로서의 산술연산
바이너리 덧셈 알고리듬(Binary Addition Algorithm)
addu 명령
예제 프로그램
프로그램 실행
2의 보수식의 값을 음수로 바꾸기
Recent Posts
Archive Posts
Tags