Machine-Level Programming

김민욱·2025년 4월 18일

이 포스팅은 Intel x86 아키텍쳐를 기준으로 작성하였습니다.

Architecture(아키텍쳐; ISA)

CPU가 이해할 수 있는 Machine/Assembly 코드의 집합

  • Machine code: 프로세서가 실행하는 Byte-level 프로그램
  • Assembly code: Machine code의 텍스트 표현

Assembly/Machine Code
CPU
PC(Program Counter): 다음 명령의 주소를 담고있음.
Registers: 프로그램 실행 중 자주 사용되는 데이터 저장
Condition Codes: 최근에 CPU가 수행한 연산 결과 정보 저장.

Memory
주소 지정이 가능한 Byte 배열
코드와 유저의 데이터 저장
스택을 통한 절차 지원

컴파일 과정
C program -> Asm program // text
-> Object progran -> Executable program // binary

Object Code
Assembler를 통해 .s 파일을 .o 파일로 전환
각 Assembly 명령어를 Byte encoding
-> 실행 코드의 거의 완성된 이미지
다른 파일의 코드 간 링크가 누락됨

  • 컴파일 예시 (gcc -Og -S sum.c)
// C code (sum.c)
long plus(long x, long y);

void sumstore(long x, long y, long *dest)
{
	long t = plus(x, y);
    *dest = t;
}
// x86-64 Assembly
sumstore:
	pushq %rbx
    movq %rdx, %rbx
    call plus
    movq %rax, (%rbx)
    popq %rbx
    ret

Assembly

  • 자료형
    Integer(1, 2, 4, 8 bytes)
    Floating Point(4, 8, 10 bytes)
    Code는 명령어를 인코딩한 바이트 시퀀스다.

  • 연산
    register와 memory의 데이터를 사용한 산술연산
    register와 memory간의 데이터 전송 연산
    점프와 조건문 등의 제어문

Register

  • 일반 목적 레지스터
    %rax: 산술 연산에 주로 사용
    %rbx: 데이터 저장에 주로 사용
    %rcx: 반복 작업에 주로 사용
    %rdx: 입출력 작업에 주로 사용
    %rsi: 문자열 작업에 주로 사용
    %rdi: 문자열 작업에 주로 사용

  • 스택 및 베이스 포인터 레지스터
    %rsp: 스택의 현재 위치
    %rbp: 스택 프레임 주소

  • 추가 일반 목적 레지스터
    %r8 ~ %r14

Assembly 명령어

movq

movq Src Dest

Src 레지스터의 값을 Dest 레지스터로 복사
Src 자리에는 Immediate data, register, memory가 올 수 있다.

leaq (load effective address)

leaq Src, Dest

Src의 주소 계산을 수행하여 Dest에 저장
메모리에 접근하지 않고 주소만 가지고 연산 가능

단순 주소 계산)

leaq 0x10(%rbx), %rax 
// %rbx로부터 0x10만큼 떨어진 주소 %rax에 저장

복합 주소 계산)

leaq (%rbx, %rcx, 4), %rax
// %rbx+%rcs*4의 주소 %rax에 저장

단순 연산)

leaq (%rdi, %rdi, 2), %rax
// rdi+rdi*2 수행 후 %rax에 저장

산술 연산

addq Src, Dest

-> Dest = Dest + Src

subq Src, Dest

-> Dest = Dest - Src

imulq Src, Dest

-> Dest = Dest * Src

salq Src, Dest // (==shlq)

-> Dest = Dest << Src

sarq Src, Dest // (for signed)

-> Dest = Dest >> Src (0으로 채움)

shrq Src, Dest // (for unsigned)

-> Dest = Dest >> Src (msb로 채움)

xorq Src, Dest

-> Dest = Dest^Src

andq Src, Dest

-> Dest = Dest & Src

orq Src, Dest

-> Dest = Dest | Src

incq Dest

-> Dest = Dest + 1

decq Dest

-> Dest = Dest - 1

negq Dest

-> Dest = -Dest

notq Dest

-> Dest = ~Dest

예제 (C to Assembly)

// C code
long arith (long x, long y, long z)
{
	long t1 = x + y;
    long t2 = z + t1;
    long t3 = x + 4;
    long t4 = y * 48; 
    long t5 = t3 + t4;
    long rval = t2 * t5;
   
    return rval;
}
RegisterUse(s)
%rdiArgument x
%rsiArgument y
%rdxArgument z
%raxt1, t2, rval
%rdxt4
%rcxt5
// Assembly code
artih:
	leaq (%rdi, %rsi), %rax // t1 = x+y
    addq %rdx, %rax // t2 = z+t1
    leaq (%rsi, %rsi, 2), %rdx // t4 = 3*y
    salq $4, %rdx // t4 = 3*y*16
    leaq 4(%rdi, %rdx), %rcx // t5 = x+t4+4
    imulq %rcx, %rax // rval = t2 * t5
    ret

<참고자료>
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition
안성용, "시스템 소프트웨어", 부산대학교

0개의 댓글