데이터 이동 인스트럭션 [ 크래프톤 정글 18일차 ]

jinsung·2025년 5월 30일

크래프톤 정글 9기

목록 보기
16/59

어제 오퍼랜드에 관해서 글을 작성했는데요.

가장 많이 사용되는 인스트럭션(명령)은 데이터를 한 위치에서 다른 위치로 복사하는 명령입니다.

오퍼랜드 표시방법의 일반성 때문에 여러 개의 인스트럭션이 필요했을 이동 인스트럭션이 간단해졌어요.

그래서 이번에는 어떤 데이터 이동 인스트럭션이 있는지 그 종류를 말해보려 합니다.

들어가기 전에

우선, 인스트럭션 명령어들을 살펴보기 전에 알아야 할 정보가 하나 있어서 그것부터 짚고 넘어갈게요.

서문. 데이터의 형식

인텔 프로세서들이 16비트 구조를 사용하다가 추후에 32비트로 확장했기 때문에
인텔은 "워드"라는 단어를 16비트 데이터 타입을 말할 때 사용해요.

여기에 기초해서

  • 32비트는 '더블 워드' 라고 하구요.
  • 64비트는 '쿼터 워드' 라고 합니다.
  • 8비트는 그냥 '바이트' 예용 ㅎㅎ

그래서 이걸 표로 한번 살펴보면..!

C Data TypeAssembly SuffixSize (Bytes)설명
charb (byte)1부호 있음: signed char
shortw (word)216비트 정수
intl (long)432비트 정수 (x86 기준)
longq (quad)864비트 정수 (x86-64 기준)
char *q (quad)8포인터는 64비트 (주소)
floats (scalar)4단정도 부동소수점
doublel (long)8배정도 부동소수점

1바이트(8bit)는 'b'
2바이트(16bit)는 'w'
4바이트(32bit)는 'ㅣ'
8바이트(64bit)는 'q' 입니다.

이것은 인스트럭션에서 접미사로 쓰이니까 알아둬야해요.

Q: 근데 4바이트는 double word 인데 왜 접미사가 'L' 이냐고요?

  • A: 'LONG WORD' 래요.

Q: int도 'l' 접미사고 double도 'l' 접미사인데 헷갈리지 않냐고요?

  • A: 쓰는 인스트럭션이 달라서 겹칠일이 없으니까 ㄱㅊ아요

자 이제 접미사 알았으니까 이동 인스트럭션 쓰러 부릉~ 가요~!

1. 간단한 데이터 이동 인스트럭션

어셈블리 명령어설명원본 크기 → 목적지 크기C 코드 예시
movb바이트 복사1B → 1Bchar a = b;
movw워드 복사2B → 2Bshort a = b;
movl더블워드 복사4B → 4Bint a = b;
movq쿼드워드 복사8B → 8Blong a = b; 또는 char *p = q;

이건 정말 간단한 데이터 이동 인스트럭션인데요.

mov 가 제일 앞에 있고 그 뒤에 접미사로
"b" , "w" , "l" , "q" 가 있죠?

해당 사이즈와 동일한 사이즈로 데이터를 이동시킨다는 뜻입니다.

별 거 없죠?

실제로 어떤 c 명령어가 어셈블리에서 변경되는지 보기 쉬우라고 c코드 예시도 적어놨어요.

감사합니다 챗선생님.

2. 0으로 확장하는 데이터 이동 인스트럭션

" 0의 확장 " 아시죠?

movz < 접두사가 붙은 인스터럭션들은 목적지의 남은 바이트들을 전부 0으로 채워줘요.

그래서 mov 뒤에 z 가 붙었답니다?

어셈블리 명령어설명원본 크기 → 목적지 크기C 코드 예시
movzbwZero-extend byte → word1B → 2Bunsigned short a = (unsigned char)b;
movzblZero-extend byte → long1B → 4Bunsigned int a = (unsigned char)b;
movzbqZero-extend byte → quad1B → 8Bunsigned long a = (unsigned char)b;
movzwlZero-extend word → long2B → 4Bunsigned int a = (unsigned short)b;
movzwqZero-extend word → quad2B → 8Bunsigned long a = (unsigned short)b;

movz 뒤에는
"bw" , "bl" , "bq" , "wl" , "wq" 가 붙었는데요.

어떤 사이즈로 변경되는지 명시하는거예요.

bw 는 byte => word
bl 는 byte => double word
bq 는 byte => quater word
wl 는 word => double word
wq 는 word => quater word

그리고 남는 비트는 0으로 채워주기!

엥??? 근데 님아
왜 movzlq 없음?

double word => quater word 가 없는데?????

짜잔~ 그거는 movl 로 대체하기로 했답니다.

movl 명령어는 4바이트 데이터를 복사할 때, 상위 비트를 0으로 채우기로 했는데요.

그건 상위비트를 0으로 채우는 movzlq 명령어랑 똑같잖아요?

그래서 그냥 그거로 쓰기로 했대요.

왜냐고요?

"그냥 옛날부터 그랬으니까"

3. 부호를 확장하는 데이터 이동 인스트럭션

어셈블리 명령어설명원본 크기 → 목적지 크기C 코드 예시
movsbwSign-extend byte → word1B → 2Bshort a = (char)b;
movsblSign-extend byte → long1B → 4Bint a = (char)b;
movsbqSign-extend byte → quad1B → 8Blong a = (char)b;
movswlSign-extend word → long2B → 4Bint a = (short)b;
movswqSign-extend word → quad2B → 8Blong a = (short)b;
movslqSign-extend long → quad4B → 8Blong a = (int)b;

z (zero 확장) 이랑 똑같은데 이름만 s (sign-extend)로 바뀌었네~~

그리고 movzlq 는 0으로 채우는 거라 없었는데
movslq 는 부호 확장이라 있습니다!

정리

책으로 읽을땐 어려웠는데

이동 > 0의 확장 > 부호 확장 순으로 가니까 차이가 확 보이고 쉽죠?

mov 는 굉장히 많이 일어나는 인스트럭션이라 외워두시면

어셈블리어를 읽고 작성하는데 많은 도움이 될 것 같아요.

0개의 댓글