본문 바로가기
C++/강의 정리

[C++ 섹션 1.어셈블리 언어 입문] 3- 레지스터 기초

by 몽실이 2022. 1. 4.
인프런 강의 "[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문"
강의를 정리한 글입니다.

 

데이터 단위


  • 8 bit = 1 byte
  • 16 bit = 2 byte = 1 word
  • 32 bit = 4 byte = 2 word = 1 dword(double-word)
  • 64 bit = 8 byte = 4 word = 1 qword(quard-word)

 

레지스터 사용 이유


컴퓨터 구조 (메인 메모리 = RAM)

  • 데이터 저장공간 크기

레지스터 < 메인 메모리 < 하드디스크 

 

  • 데이터 접근 속도

레지스터 > 메인 메모리 > 하드디스크

 

접근 속도와 저장공간은 반비례

 

cpu가 연산을 할 때 중간 결과물을 임시 저장하는 용도로 cpu내부에 있는 레지스터 사용

레지스터는 cpu 내부에있기 때문에 접근 속도가 빠르기 때문에 대신 용량이 적다.

 

레지스터 구성


레지스터 구성 이미지

일반적으로 프로그래밍에선 왼쪽 위 A, B, C, D 네 가지만 사용한다.

 

레지스터 내부 구조

각 레지스터에서 데이터 사용 범위로 또 나뉜다.

  • 64 bit = rax
  • 32 bit = eax
  • 16 bit = ax
  • 8 bit = ah, al

여기서 a를 b, c, d 로 바꾸면 다른 레지스터에 접근하는 것이다. ex) ebx, rcx, dx

 

SASM


키워드 mov

  • 원하는 데이터 공간의 데이터 값을 넣는 키워드
  • 사용법 : mov [데이터 공간], [데이터 값]

ex) mov reg(레지스터), cst(숫자) - mov reg1(레지스터), reg2(다른 레지스터)

ex) mov rax, 0x1234 - 레지스터 rax에다가 0x1234 16진수 값을 넣는 코드

  • 메모리에 데이터를 넣을 경우 mov [메모리 이름], 사이즈, 데이터 값 - 메모리이름에 [] 쳐줘야 주소값이 아닌 데이터에 들어간다.
  • 메모리에 레지스터 값을 넣을경우 레지스터는 자체 사이즈가 정해져서 사이즈 입력이 필요 없다.

ex) num 이란 1바이트 데이터가 있을 경우 - mov [num] 0x12

 

%include "io64.inc"

section .text
global CMAIN
CMAIN:
    mov rbp, rsp; for correct debugging

    ; mov reg1(레지스터), cst(숫자)
    ; mov reg1, reg2 - 오른쪽 값이 왼쪽으로 이동

    mov eax, 0x1234
    mov rbx, 0x12345678
    ;mov cl, 0xffffffff ; [Error]범위 cl 1byte보다 큰 수 들어가서 에러
    mov cl, 0xff
    
    mov al, 0x00
    mov rax, rdx
    
    mov [num], byte, 0x12 ; 메모리 이름에 [] 쳐주고 사이즈, 상수로 해줘야한다.
    mov [num], al ; 레지스터 넣을땐 레지스터 자체 크기가있어서 사이즈 입력X
    
    xor rax, rax
    ret
    
section .data
	num db 0x00

 

Debug

  • F5를 눌러 Debug 모드를 실행해서 코드를 한 줄씩 실행할 수 있다.
  • Debug  툴바를 클릭해서 현재 코드 상 Register, Memory 값들을 볼 수 있다.
  • 마커 기능 - 마커를 찍고 싶은 라인을 클릭하면 빨간 점으로 마커가 생성된다.
  • 디버그 모드에서 F5를 클릭 시 마커가 있는 곳까지의 코드를 전부 실행시키고 이동한다.

Debug 실행 예시

 

레지스터 크기의 따른 값 설정

  • 레지스터 크기의 따라서 데이터 입력 값이 정상적이지 않을 수 있다.

ex)

현재 코드 상에서 16번째 라인에서 eax 즉 a레지스터에 4byte 크기로 0x1234 값을 넣고

21번째 라인에서 a레지스터에 1 byte 크기로 0x00을 넣어서 rax에 0x00이 있을 거 같지만
디버그를 찍어 rax레지스터를 보면 0x1200이란 값이 나온다.

 

그 이유는 비트 값으로 보면 알 수 있다.

16번째 라인에 rax의 값

16번째 라인에서 eax(32 bit) 즉 4 byte(dword) 값으로 들어가 있는데

21번째 라인에서 al(8 bit) 값으로 0x00을 넣으면

21번째 라인에 rax의 값

이렇게 al의 크기 8 bit 만 0의 값이 들어가고 사이즈 크기 때문에 al이 관여하지 못하는 eax의 나머지 비트의 
값이 남아있어서 0x1200이란 값이 나온다.

eax 로 초기화

같은 데이터 크기 eax로 0x00을 입력 시 0x0으로 의도한 값이 나오는 걸 확인할 수 있다.