Machine Programming : Basics

임승섭·2023년 4월 20일
0

Computer Systems

목록 보기
1/7
post-thumbnail

Definitions

  • Architecture(ISA : Instruction set architecture)
    : The parts of a processor design that one needs to understand for writing assembly/machine code

  • Microachitecture
    : Implementation of the architecture
    ex). cache size, core frequency

  • Machine code
    : The byte-level programs that a processor executes

  • Assembly code
    : A text representation of machine code

Programmer-Visible State

  • PC(program counter) (%rip)
    : 실행할 다음 instruction의 메모리 주소를 가리킨다.
  • Register file
    : heavily used program data
  • Condition codes
    : 가장 최근에 실행한 산술(arithmetic) 또는 논리(logical) 연산(operation)에 관한 상태 정보(status information) 저장.
    : if나 while문을 구현할 때 필요한 제어나 조건에 따른 데이터 흐름의 변경을 구현하기 위해 사용된다. (used for conditional branching)
  • Memory
    : Byte addressable array
    : Code and user data
    : Stack to support procedures

x86-64 Integer Registers

  • %rax : return value
  • %rbx : callee saved
  • %rcx : 4th argument
  • %rdx : 3rd argument
  • %rsi : 2nd argument
  • %rdi : 1st argument
  • %rbp : callee saved
  • %rsp : stack pointer (런타임 스택의 끝 부분을 가리킨다)
  • %r8 : 5th argument
  • %r9 : 6th argument
  • %r10 : caller saved
  • %r11 : caller saved
  • %r12 : callee saved
  • %r13 : callee saved
  • %r14 : callee saved
  • %r15 : callee saved

Assembly : Operation

Transfer data between memory and register

  • Load data from memory into register
  • Store register data into memory

Perform arithmetic function on register or memory data

Transfer control

  • Unconditional jumps to/from procedures
  • Conditional branches
  • Indirect branches

Most x64 instructions are two-operand :

  • moveq src, dst
    : move "quad-word(64 bits)" from src to dst
    (source와 destination은 register가 될 수도, memory가 될 수도 있다)

  • addq src, dst
    : dst += src

  • subq src, dst
    : dst -= src

Moving data

movq Source, Dest

movb, movw, movl, movq
(move byte, word, double word, quad word)
1, 2, 4, 8 bytes
8, 16, 32, 64 bits

Operand Types

  • Immediate : Constant integer data
  • Register : One of 16 integer registers
  • Memory : 8 consecutive bytes of memory at address given by register

Example

movq src, dst

// Imm, Reg
movq $0x4, %rax			// temp = 0x4;

// Imm, Mem
movq $-147, (%rax)		// *p = -147

// Reg, Reg
movq %rax, %rdx			// temp2 = temp1

// Reg, Mem
movq %rax, (%rdx)		// *p = temp

// Mem, Reg
movq (%rax), %rdx		// temp = *p

Simple Memory Addressing Modes

Normal : (R) -> Mem[Reg[R]]

  • Register R specifies(=stores) memory address (to read from or write to)
  • Pointer dereferencing in C
  • movq (%rcx), %rax

주소를 통해 그 값에 접근하는 것을 역참조(dereference)라고 합니다

Displacement : D(R) -> Mem[Reg[R]+D]

(want to jump. D : integer. +D means 'other location')

  • Register R specifies start of memory region
  • Constant displacement D specifies offset (in bytes)
  • movq 8(%rbp), %rdx

Example

whatAmI : 
	movq (%rdi), %rax
    movq (%rsi), %rdx
    movq %rdx, (%rdi)
    movq %rax, (%rsi)
void swap(long *xp, long *yp) {
	long t0 = *xp;
    long t1 = *yp;
    *xp = t1;
    *yp = t0;
}

// argument *xp = %rdi, *yp = %rsi
  • ppt에 그림 보면 이해가 더 쉽다.

Complete Memory Addressing Modes

Most General Form : D(Rb, Ri, S) / Mem[Reg[Rb]+S*Reg[Ri]+D]

  • D : Constant "displacement" 1, 2, or 4 bytes
  • Rb : Base register : Any of 16 integer registers
  • Ri : Index register : Any, except for %rsp
  • S : Scale : 1, 2, 4 8

Special Cases :

(Rb, Ri) / Mem[Reg[Rb] + Reb[Ri]]
D(Rb, Ri) / Mem[Reg[Rb] + Reg[Ri] + D]
(Rb, Ri, S) / Mem[Reg[Rb] + S * Reg[Ri]]

Address Computation Examples

%rdx : 0xf000
%rcx : 0x0100
일 때,

1). 0x8 (%rdx)
= 0xf000 + 0x8
= 0xf008

2). (%rdx, %rcx)
= 0xf000 + 0x100
= 0xf100

3). (%rdx, %rcx, 4)
= 0xf000 + 4 * 0x100
= 0xf400

4). 0x80(, %rdx, 2)
= 2 * 0xf000 + 0x80
= 0x1e080

Arithmetic & Logical operation

Load Effective Address 유효주소 적재

leaq Src, Dst

  • 메모리를 전혀 참조하지 않는다.
  • Src는 메모리 참조처럼 보이지만, 가리키는 위치에서 읽기를 수행하는 대신 유효주소를 목적지에 복사한다.
  • 일반적인 산술연산을 간결하게 설명하기 위해 사용된다.
  • Computing addresses without a memory reference
    translation of p = &x[i];
  • Computing arithmetic expressinos of the form x + k*y
    k = 1, 2, 4, 8
long scale(long x, long y, long z) {
	long t = x + 4*y + 12*z;
    return t;
}
x in %rdi, y in %rsi, z in %rdx
scale :
	leaq (%rdi, %rsi, 4), %rax	// x + 4y를 %rax에 저장
    leaq (%rdx, %rdx, 2), %rdx  // z + 2z를 z에 저장
    leaq (%rax, %rdx, 4), %rax  // (x+4y) + 4*(3z)를 %rax에 저장
    ret

leaq 더 연습

p in %rbx, q in %rdx

Q.
(1). leaq 9(%rdx), %rax
(2). leaq (%rdx, %rbx), %rax
(3). leaq (%rdx, %rbx, 3), %rax
(4). leaq 2(%rbx, %rbx, 7), %rax
(5). leaq 0xE(, %rbx, 3), %rax
(6). leaq 6(%rbx, %rdx, 7), %rax

A.
O (1). t1 = q + 9
O (2). t1 = p + q
O (3). t1 = q + 3 * p
O (4). t1 = (p + 7 * p) + 2		 -> 8p + 2
O (5). t1 = (0 + p * 3) + 0xE	 -> 3p + 14
O (6). t1 = (p + q * 7) + 6

Some Arithmetic Operation

Two Operand Instruction

addq	src, dst	// dst = dst + src
subq	src, dst	// dst = dst - src
imulq	src, dst	// dst = dst * src
salq	src, dst	// dst = dst << src
sarq	src, dst	// dst = dst >> src
shrq	src, dst	// dst = dst >> src
xorq	src, dst	// dst = dst ^ src
andq	src, dst	// dst = dst & src
orq		src, dst	// dst = dst | src

One operand Instruction

incq	dst		// dst = dst + 1
decq	dst		// dst = dst - 1
negq	dst		// dst = -dst
notq	dst 	// dst = ~dst

Arithmetic Expression Example

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;
}
x in %rdi, y in  %rsi, (z, t4) in %rdx, (t1, t2, rval) in %rax, t5 in %rcx
arith :
	leaq (%rdi, %rsi), %rax		// t1(%rax)에 x + y 저장
    addq %rdx, %rax				// t2(%rax) = t1 + z
    leaq (%rsi, %rsi, 2), %rdx	// z에 일단 3y 저장.
    salq $4, %rdx				// z = 16 * (3y) = 48 * y
    leaq 4(%rdi, %rdx), %rcx	// t5 = x+4[t3] + 48y[t4]
	imulq %rcx, %rax			// t2 * t5

C, assembly, machine code

  • p1.c, p2.c 2개의 C 프로그램이 있다고 하자.
  • gcc -Og p1.c p2.c -o p 다음과 같이 컴파일한다.
  • 컴파일러는 두 소스파일의 어셈블리 버전 p1.s와 p2.s를 생성한다.
  • 어셈블러는 어셈블리 코드를 바이너리 목적코드 p1.o와 p2.o로 변환한다.
  • 링커는 두 목적코드 파일을 최종 실행파일인 p로 변환한다.

Example

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;
}

Generated x86-64 Assembly

sumstore :
	pushq	%rbx	// %rbx가 프로그램 스택에 저장(push)되어야 한다는 걸 의미한다
    movq	%rdx, %rbx
    call 	plus
    movq	%rax, (%bx)
    popq	%rbx
    ret
  • *dest = t; in C code
    : Store value t where designated by dest

  • movq %rax, (%rbx)
    : Move 8-byte value to memory (quad words)

    • t : %rax
    • dest : %rbx
    • *dest : M[%rbx]
  • 0x40059e : 48 89 03
    : 4 byte instruction
    stored at address 0x40059e

0개의 댓글