Assembly Programmer's View
Programmer-Visible State
- PC: Program Counter
- Address of next instruction: 다음 명령의 주소값을 갖습니다.
- Called "RIP" (instruction pointer register in x86-64)
- Register File: 데이터가 있는 곳을 그냥 File이라고 부릅니다. 그냥 Register공간입니다.
- Heavily used program data: 자주 사용하는 프로그램의 데이터가 있는 공간입니다.
- Condition Codes: CPU안에 있는 또 다른 메모리공간
- Store status information about most recent arithmetic operation
- Used for conditional branching: 조건을 분기하는 경우에 사용합니다.
- Memory
- Byte addressable array: 주소값은 Byte단위로 이루어집니다.
- Code, user datam (some) OS data
- Stack used to support procedures
각각의 registers들은 64bits, 즉 8byte단위로 이루어져있습니다. 하지만 Integer type과 같은 4byte데이터도 담을 수 있게 4byte단위 주소값도 있습니다. 마찬가지로 2byte, 1byte단위로 끊겨있는 주소값도 있습니다.
이때 %rsp나 %esp는 stack을 위한 register로 다른 registers들과는 달리 범용 register가 아닙니다. 따라서 일반적인 데이터를 담을 수는 없습니다.
Moving Data
movq Source, Dest
와 같은 어셈블리 명령어를 통해 데이터를 옮길 수 있습니다.
Operand types
피연산자가 될 수 있는 종류는 아래의 3종류입니다:
- Immediate: Constant integer data: 상수 데이터입니다.
- notation: $는 상수임을 나타내고 0x는 16진수를 나타냅니다.
- Example: $0x400, $-533
- Encoded with 1,2 or 4bytes: 데이터의 형식에 따라 달라집니다.
- Register: One of 16 integer registers
- notation: %는 register임을 나타냅니다.
- Example: %rax, %r13
- But, %rsp reserved for special use: %rsp는 특별한 용도로 사용되는 register입니다.
- Others have special uses for particular instructions
- Memory: 8 consecutive bytes of memory at address given by register: 64bits의 운영체제에서는 8bytes의 주소값을 갖는데, 이는 register에 저장됩니다.
- notation: ()는 memory공간임을 나타냅니다.
- Simplest example: (%rax)
단, memory에서 memory로의 move는 하나의 명령으로 실행할 수 없고, memory → register → memory의 두 번의 명령으로 수행할 수 있습니다.
Using Simple Addressing Modes
// C code
void swap(long *xp, long *yp)
{
long t0 = *xp;
long t1 = *yp;
*xp = t1;
*yp = t0;
}
// Assembly code
swap:
movq (%rdi), %rax
movq (%rsi), %rdx
movq %rdx, (%rdi)
movq %rax, (%rsi)
ret
위 코드를 메모리와 레지스터 단에서 그림으로 이해해보겠습니다.
Complete Memory Addressing Modes
- Most General Form
- D(Rb,Ri,S) → Mem[Rb + S*Ri + D]
- D: Constant "displacement" 1,2 or 4bytes
- Rb: Base register: Any of 16 integer register: base가 되는 register의 값, memory의 주소값의 기준이 되는 주소값
- Ri: Index register: Any, except for %rsp: Index에 해당하는 register의 값, list의 경우 index를 구하기 위함
- S: Scale: 1,2,4 or 8: list에서 자료형이 차지하는 크기
- Special Case
- D(Rb) → Mem[Bb + D]
- (Rb, Ri) → Mem[Rb + Ri]
- D(Rb,Ri) → Mem[Rb + Ri + D]
- (Rb,Ri,S) → Mem[Rb + S*Ri]
- 지금까지 써왔던 memory표기법은 (Rb)인것 입니다.
Some Arithmetic Operation
- Two Operand Instructions:
- addq Src,Dest → Dest = Dest + Src
- subq Src,Dest → Dest = Dest - Src
- imulq Src,Dest → Dest = Dest * Src
- One Operand Instructions:
- Incq Dest → Dest = Dest + 1
- decq Dest → Dest = Dest - 1
- negq Dest → Dest = - Dest
- notq Dest → Dest = ~ Dest
Race condition
이제 Race condition이 발생하는 예시를 보겠습니다.
// C code
my_sighandler(){
...
*i = *i + value;
...
}
main(){
...
for(k=0; k<N; k++) {
...
*i = *i + value;
...
}
}
// Assembly code
my_sighandler:
...
movq (%rax), %ecx
addl %eax, %ecx
movq %ecx, (%rax)
...
ret
main:
...
movq (%rax), %edx
addl %eax, %edx
movq %edx, (%rax)
...
ret
}
위 그림을 보면 main에서 process가 진행되다가, signal이 도착해서 sighandler쪽으로 control이 넘어갑니다. 이때 main쪽에서 (%rax)의 값을 미처 수정하지 못한 상태에서 sighandler가 호출이 되었기 때문에, 최종적으로 (%rax)의 값이 3이 아닌 2가 저장되는 모습을 볼 수 있습니다.
2024.09.24 - [학교 수업/시스템 프로그래밍] - [시스템 프로그래밍] Signal Programming
위 글 마지막 부분에서 봤었던 문제도 같은 종류의 문제입니다.
addjob과 deletejob이 공통의 자료구조를 열람할 수 있기 때문에, 만약 한쪽이 미처 수행이 끝나지 않은 상태에서 signal이 불려 다른 쪽에서 동작을 수행한다면 Race condition이 발생할 수 있는것입니다.
이렇게 일반 C code단에서는 보지 못했던 문제들을 Assembly단에서 보면 볼 수 있습니다.
Critical Section
Critical Section is a piece of code that accesses a shared resource(e.g., shared variable). so, critical section must not be concurrently executed by more than one thread.
Critical section(* 임계 구역)은 공통된 자원에 접근하는 코드를 말하며, 이는 하나의 쓰레드이상이 동시에 실행해서는 안됩니다.
Mutual exclusion guarantees that if one thread is executing within the critical section, the others will be prevented from doing so.
Mutual exclusion(* 상호 배제)는 하나의 쓰레드에서 임계 구역에 해당하는 코드를 실행중이라면 다른 이들이 실행하지 못하도록 하는것을 보장합니다.
위 예시의 경우에는 addjob을 실행하고 있다면 deletejob과 같은 명령을 addjob이 끝날때까지 실행하지 못하도록 막는것은 상호 배제의 원리를 따른다고 말 할 수 있는것입니다.
이런 경우 Atomic하다고 하는데, 원자와 같이 더 이상 이 코드의 실행 권한을 쪼갤 수 없는 상태를 말합니다.
추가
addl, addq처럼 명령어 뒤에 붙는 접미사는 크게 4가지로,
q, l, w, b가 있습니다. 이는 각각 8, 4, 2, 1byte를 의미합니다.
예를 들어 movq같은 경우는 register의 주소값이 8byte단위이기 때문에 q를 붙여주었고,
위에서 들었던 예시들 중 addl같은 경우는 addl의 Dest나 Src가 integer이기 때문에, 4bytes 연산을 수행했습니다.
https://learncom1234.tistory.com/66
'[학교 수업] > [학교 수업] 시스템 프로그래밍' 카테고리의 다른 글
[시스템 프로그래밍] Assembly Language (1) | 2024.10.06 |
---|---|
[시스템 프로그래밍] Signal Examples (1) | 2024.10.06 |
[시스템 프로그래밍] Signal Programming (0) | 2024.09.24 |
[시스템 프로그래밍] Signals (0) | 2024.09.20 |
[시스템 프로그래밍] Linux Commands (0) | 2024.09.20 |