SungJin Kang

SungJin Kang

hour30000@gmail.com

© 2024

Dark Mode

Addressing Mode ( 주소 지정 모드 )

Addressing Mode ( 주소 지정 모드 )는 명령어의 연산이 수행되기 전 명령어의 피연산자를 어떻게 해석하고 읽을지에 대한 규칙이다.
이 글에서는 총 7가지의 Addressing Mode를 알아볼 것이다.


Immediate Mode

명령어에 명시적으로 저장된 값이 피연산자이다.
흔히 어셈블리어를 보면 상수 값 자체가 어셈블리에 들어간 경우가 이 경우이다.

li $11, 3 // 11번째 레지스터로 값 "3"을 쓰라 ( 여기서 3은 그냥 값, 상수 그 자체이다. )

li $9, 8 // 9번째 레지스터로 값 "3"을 쓰라

Index Mode

레지스터(인덱스 레지스터)의 값에 상수 값(변위 값)을 더하여서 피연산자의 주소를 얻는 방식이다. 몇번 째 인덱스 레지스터인지와 더할 상수 값은 명령어 코드에 포함되어 있다. 인덱스 모드는 데이터가 연속되어 있는 배열의 한 element에 접근하기 위해서 사용된다. 명령어 코드는 배열의 시작 주소, 인덱스 레지스터에 들어 있는 값, 현재 element의 인덱스 값을 가지고 있다. 인덱스 레지스터에 들어 있는 값을 올리거나 내려 배열의 다른 element에 접근할 수 있다.

move $3, 0 		# 3번째 인덱스 레지스터에 상수 값 0을 저장한다.      
add $3, $3,4 		# 배열의 다섯번째 element를 가리킬 수 있게 인덱스 레지스터의 값에 4를 더한다(array[4]는 5번째 element)                  
sb $0, array1($3) 	# array1[4]에 값 0을 저장한다.
			        # 이렇게 주소가 아니라 array의 시작 주소와 인덱스 레지스터를 이용해서 array의 element에 접근하는 것이 Index Mode이다.   

Indirect Mode ( Indirect Register Mode, 간접 주소 모드 )

피연자의 유효한 주소(진짜 주소)는 레지스터 혹은 메인 메모리 위치 혹은 명령어에 들어 있는 주소의 위치이다. 간접 모드는 흔히 명령어에서 괄호로 주어진 메모리 주소 혹은 레지스터의 이름을 생각하면 된다. 피연산자의 주소를 포함하는 다른 메모리 주소 혹은 레지스터가 포인터이다. 간접 모드에서 CPU는 위에서 말한 어떤 메모리 주소로 가는데 이 메모리 주소에는 피연산자가 있는게 아니라 피연산자의 주소가 있는 것이다.

이렇듯 간접 모드에서는 피연산자의 값을 얻기 위해서는 두 번의 메모리 접근이 요구된다.

아래와 같은 C코드가 있다.
int *alpha=0x00002004, q=5;
*alpha = q;

위의 코드는 아래의 어셈블리 언어로 바뀐다.

alpha: word 사이즈의 값 "0x00002004" # alpha는 주소를 가지고 잇는 변수이다.
                                     # 그 주소 값은 0x00002004이다.
q: word 사이즈의 값 "5"

....

lw $10,q 	    # q에서 word size 만큼의 데이터를 레지스터 10에 저장
		        # 10번째 레지스터는 값 "5"를 가지고 있다.
lw $11,alpha 	# 11번째 레지스터는 값 "0x00002004"를 가진다.
sw $10,($11) 	# 10번째 레지스터에 들어 있는 값을 11번째 레지스터가 가지고 있는 주소의 위치에 저장한다.
		        # 11번째 레지스터는 값 "0x00002004"를 가지고 있다.
		        # 이렇게 11번째 레지스터에 값을 저장하는게 아니라(!), 
                # 11번쨰 레지스터가 가지고 있는 주소의 위치에 값을 저장하라는 것이 Indirect Mode이다.
                # 11번째 레지스터의 주소를 한번, 11번째 레지스터가 가지고 있던 주소를 한번 총 2번 메모리 참조가 발생하였다.

-------------------------------------

array1: .byte 1,2,3,4,5,6
.text
__start:
la $3, array1 	# 3번째 레지스터에 array1의 주소를 저장하다. 
                # Direct addressing mode ( 직접 주소 모드 )이다.
add $3, $3,4 	# 3번째 레지스터에 저장된 array1의 base address에 4를 더하여 array1의 다섯번째 element의 주소를 가지게한다.
sb $0, ($3) 	# 0번째 레지스터의 1 바이트를 3번째 레지스터가 가지고 있는 메모리 주소의 위치에 저장한다.
		        # indirect addressing mode ( 간접 모드 )
                # 3번째 레지스터의 주소를 한번, 3번째 레지스터가 가지고 있던 주소를 한번 총 2번 메모리 참조가 발생하였다.

Absolute (Direct) Mode ( 직접 주소 모드 )

피연산자의 주소가 명령어 코드에 들어있는 경우이다.

beta: .word 2000

lw $11, beta 	# 11번째 레지스터에 beta의 위치에 있는 word 값을 저장한다. 
                # beta의 위치 한번만 메모리 참고가 발생
		        # 변수 beta의 주소가 어셈블리 코드에 이미 들어있다. ( 이렇게 실제 beta의 주소가 아니라 변수명으로 들어가 있을 수도 있다.)
		        # 11번째 레지스터는 값 2000을 가지게 된다.

Register Mode ( 레지스터 모드 )

CPU 레지스터의 이름(몇 번째 인지)가 명령어 코드에 들어가 있다.
그리고 레지스터는 피연산자의 값을 가지고 있다.
몇번 째 레지스터를 나타내는지의 숫자를 표현하기 위한 bit 수는 CPU마다 다르다.

add $14,$14,$13     # 14번째 레지스터가 가지고 있는 값에 13번째 레지스터가 가지고 있는 값을 더하여 14번째 레지스터에 저장한다.

레지스터 모드에서는 피연사자를 얻기 위해 메모리에 접근할 필요가 없다. ( 당연하다 레지스터에서 피연사자를 가져오기 때문이다. )


Displacement Mode ( 변위 주소 지정 모드 )

인덱스 모드에서 인덱스 레지스터가 사용된다는 점을 제외하고 인덱스 레지스터와 비슷하다.
베이스 레지스터는 메모리 위치로의 포인터를 가지고 있다.
정수 값이 변위 값을 나타낸다.
피연산자의 주소는 베이스 레지스터에 위의 변위 값을 더하여 얻을 수 있다.
인덱스 모드와 변위 주소 지정 모드의 차이는 변위 값을 표현하기 위해 배정된 bit의 수가 다르다는 것이다.
변위 값이 메모리에 접근하기 위한 bit의 수를 나타내는 경우는 인덱스 모드이다.
인덱스 모드는 배열 접근에서 주로 사용되고 변위 주소 지정 모드는 구조체 내의 변수에 접근할 때 주로 사용된다.

.data
student: .word 10000 #field code
.ascii "Smith" #field name
.byte # field test
.byte 80,80,90,100 # fields hw1,hw2,hw3,hw4
.text
__start:
la $3, student 	# 3번째 레지스터에 구조체 student의 주소를 저장한다.
		        # 3번쨰 레지스터는 베이스 레지스터로서의 역할을 한다.
add $17,$0,90 	# 17번째 레지스터는 값 "90"을 가진다.
sb $17, 9($3) 	# 베이스 레지스터($3)으로 부터 9byte만큼 떨어진 위치(변수 "test")에 17번째 레지스터가 가지고 있는 값을 저장한다."
		        # displacement addressing mode

Autoincrement /Autodecrement Mode ( 자동증가 / 자동감소 모드 )

간접 레지스터 모드의 특별한 경우이다. 명령어 코드에 들어있는 N번째 레지스터는 피연산자의 주소를 가진다. 연산 후 레지스터의 값이 1 증가하거나 1 감소한다.

MIPS는 autoincrement/autodecrement mode를 가지고 있지 않다.

MOV.B @R8+,R9   # 8번째 레지스터에서 9번 째 레지스터로 Byte 데이터를 복사한다.
                # 그 후 8번째 레지스터의 값을 1 올린다.

references : http://www.cs.iit.edu/~cs561/cs350/addressing/addsclm.html