태초의 프로그래밍 언어 어셈블리

assembly, 8086, x86

메모리 주소 표현 방법들

이전 글에서 ds:[bx]라는 가장 간단한 메모리 주소 표현 방법을 보았습니다. 이번에는 그 외에 어떤 방법들이 있는지를 보겠습니다.

다음 테이블이 바로 메모리 주소의 모든 표현 방식을 모아놓은 것입니다.

[BX + SI]
[BX + DI]
[BP + SI]
[BP + DI]
[SI]
[DI]
d16 (변수의 오프셋)
[BX]
[BX + SI + d8]
[BX + DI + d8]
[BP + SI + d8]
[BP + DI + d8]
[SI + d8]
[DI + d8]
[BP + d8]
[BX + d8]
[BX + SI + d16]
[BX + DI + d16] 
[BP + SI + d16]
[BP + DI + d16]
[SI + d16]
[DI + d16]
[BP + d16]
[BX + d16]

d8은 8비트의 숫자를 말하고 d16은 16비트의 숫자를 말합니다.

가만히 보면 첫번째에 나오는 레지스터가 bx, bp이고 그 다음이 si,di 이고 그 다음이 숫자라는 규칙이 있는걸 알 수 있습니다. bx, bp의 이름이 베이스 레지스터, 베이스 포인터 레지스터라는 것을 보면 bx, bp는 항상 기본 주소를 나타낸다는 것을 알 수 있습니다. 또 si, di의 이름이 소스 인덱스 레지스터, 목적destination 인덱스 레지스터라는 것을 보면 베이스 주소에 더하는 인덱스라는 것이 생각납니다. C언어 하시는 분들은 뭔가 생각나는거 없으세요? 힌트는 배열입니다. (주1)

 

실습 코드를 보겠습니다.

org 100h
mov ax, 0b800h
mov ds, ax
mov bx, 0
mov cl, 'A'
mov ch, 11011111b
mov ds:[bx], cx
mov [bx+2], cx
mov si, 4
mov [bx+si], cx
mov [bx+si+2], cx
ret

일단 실행하기 전에 코드를 보면서 A라는 글자가 화면에 몇번 나올지 생각해보세요. 메모리에 데이터를 쓰는 명령이 몇개 있나요? 4개입니다. [] 표시가 있는 명령어만 보면 되니까요.

그럼 메모리 주소가 각각 몇번지가 될까요?

첫번째로 메모리에 쓰는 명령어는 mov ds:[bx], cx입니다. 이때 ds값은 0b800h이고 bx 값은 0입니다. 세그먼트 주소 * 10h + 레지스터 값이 주소값이므로 0b8000h + 0h = 0b8000h 값이 주소 값입니다. 0b8000h 위치의 메모리에 'A'라는 값을 쓴 것입니다.

그 다음 명령어는 [bx+2]입니다. 세그먼트 ds 값은 0b800h이고 레지스터 값 bx에 2가 더해졌으니 0b8000h + 0 + 2 = 0b8002h 가 주소 값이 됩니다. 앞에서 쓴 메모리 주소보다 2가 더해졌지요?

그 다음은 bx+si인데 si에는 4라는 값이 있습니다. 그래서 0b8000h + 0 + 4 = 0b8004h이 메모리 주소가 됩니다. 그 다음은 bx+si+2 이므로 계산할 필요도 없이 0b8006h가 되겠지요.

한번 실행해보세요. 핑크색 A가 몇개 나왔나요?

핑크색 A들이 서로 붙어있나요 아니면 떨어져있나요?

예제에 없는 다른 형태들을 사용해서 한줄을 A로 채워보세요. 그리고 그 다음줄로 넘어가 보세요. 메모리 주소에 계속 2를 더하면 한줄 한줄 채울 수 있습니다. 색깔도 바꿔보고 글자도 다른 글자로 바꿔보세요. 색깔을 지정하는 11011111b 값을 아무 값으로나 바꿔서 해보세요.

잘된다면 이번엔 안되는걸 해보세요. d8 위치에 16비트 값을 넣어보세요. 레지스터 2개를 이용하는 [bx + si] 형태말고 [ax + bx + cx] 같이 3개의 레지스터를 써보세요. 테이블을 보면 항상 첫번째 레지스터가 bx, bp, si, di 레지스터인데 ax나 cx같이 다른 레지스터를 써보세요. 어떻게 되나요?

 


주1: 베이스 주소 + 인덱스 주소라는걸 보면 포인터 연산이 생각나야 합니다. 안그러면 C언어 개발자라고 하기에 부끄러운 겁니다. 진짜에요. 저도 포인터 연산을 생각못해서 절 가르쳐준 선배님에게 혼난 기억이 있거든요. *(p + 1), *(p + 3) 이런걸 생각해보세요. C언어가 왜 어셈블리 언어를 계승하는 언어인지 아시겠지요?

 

 

댓글

댓글 본문
작성자
비밀번호
  1. 수강생
    공대생인데 학교수업 못따라가서 쩔쩔매다가
    강의 감사하게 잘보고 따라가고 있어요!
    그런데 질문이 있어요.
    교수님께서
    Mov [bx+1000h] 34h
    같은 명령어는 문제를 야기한다는데 왜 그런지 잘모르겠어요.
    저 [] 안에 1000이 아니라 1000h가 붙어서 그런가요?
  2. 강우진
    11011111b (이진수) 값을 0x0A (16진수) 값으로 바꿔서 표현해도 되더라고요~
    다만 다른 것이 0ah 이렇게 하면 안 되고 C언어 처럼 0x0A 이렇게 16진수로 표현해야 되더라고요~

    그리고 좋은 강좌 감사드립니다~
  3. i몽당
    에뮬레이터 하단에 screen 버튼을 클릭하시고 실행해보시면....^^
  4. 핑크색
    핑크색A가 뭐죠??
  5. gurugio
    제 실수입니다. 문제되는 내용은 지웠습니다.
    알려주셔서 감사합니다.

    d8도 되고 d16도 됩니다.
    아무거나 사용해도 상관없습니다.
  6. 참치통조림
    좋은 강의 고맙습니다.

    이해가 안되는 부분이 있는데 본문 내용중
    ------------------------------------------------------
    [bx + 30] 도 되고 [bx + si + 30] 도 되는데 [bx + si + 300]은 안됩니다. 300은 8비트로 나타낼 수 있는 수가 아니기 때문입니다. 8비트는 0~255의 값을 나타낼 수 있습니다.
    ------------------------------------------------------
    위 부분은 아래 예제 변형에서 ==========> 형태로 표현이 되는데 255 이상이 안된다고 하신 뜻을 모르겠습니다. 본문에 제시해 놓으신 메모리 주소 표현방식에도 [BX + d8] 과 [BX + d16] 이 있는데 실 코팅시 프로그래머가 주의해야 할 부분이 따로 있는건가요?

    org 100h
    mov ax, 0b800h
    mov ds, ax
    mov bx, 0

    mov cl, 041h
    mov ch, 0c9h
    mov ds:[bx], cx

    mov cl, 042h
    mov [bx+2], cx

    mov cl, 043h
    mov [bx+4], cx

    mov cl, 044h
    mov [bx+6], cx

    mov cl, 045h
    mov [bx+8], cx

    mov cl, 046h
    mov [bx+10], cx

    mov cl, '-'
    mov ch, 009h
    mov si, 160
    mov [bx+si], cx
    mov [bx+si+2], cx
    mov [bx+si+4], cx
    mov [bx+si+6], cx
    mov [bx+si+8], cx
    mov [bx+si+10], cx
    mov [bx+si+12], cx

    mov cl, '>'
    mov [bx+si+12], cx

    mov cl, '='
    mov ch, 009h
    mov bx, 320
    mov [bx], cx
    mov [bx+2], cx
    mov [bx+4], cx
    mov [bx+6], cx
    mov [bx+8], cx
    mov [bx+10], cx
    mov [bx+12], cx

    mov cl, '>'
    mov [bx+12], cx

    ret
버전 관리
gurugio
현재 버전
선택 버전
graphittie 자세히 보기