gcc 명령어는 소스코드를 executable code로 바꿔달라는 명령어.
보고시프면 compiler explorer 보면 됨
저 명령어가 내려지면 내부적으로는 아래와 같이 작동하게 된다.
(주체 -> 결과물)
명령줄 옵션 -Og1은 컴파일러에게 원본 C 코드의 전체 구조를 따르는 기계 코드를 생성하도록 최적화 수준을 지시합니다.
-Og 하면 최적화라서 코드가 없에질수도. 그래서 O1(최적화 젤 빡센거)
are visible that normally are hidden from the C programmer:
long mult2(long, long);
void multstore(long x, long y, long *dest) {
long t = mult2(x, y);
*dest = t;
}
여기서 C compiler가 만든 어셈블리 코드를 보고싶으면 -S 옵션을 사용하면 된다.(대신 컴파일러까지만 동작하고 어셈블러는 동작하지 않음)
linux> gcc -Og -S mstore.c
어셈블리 코드파일은 아래와 같은 다양한 declarations 가진다.
multstore:
pushq %rbx
movq %rdx, %rbx
call mult2
movq %rax, (%rbx)
popq %rbx
ret
아래와 같이 -c 옵션을 주면 GCC가 컴파일도 하고 어셈블도 한다. 그래서 object-code 파일(16진수)을 만든다.(그래서 바로 보여지진 않음)
linux> gcc -Og -c mstore.c
그래서 int 4byte임
원래는 연산은 레지스터끼리 혹은 레지스터와 immediate 끼리만 함. 근데 아키텍처에 따라 다르기도 함.
x=7
y=0
z=x+y
x,y의 주소를 각 레지스터(r1,r2)에 올림
ADD r1, r2 이렇게 함.(레지스터를 하나 더올릴지 말지는 cpu마다 구현이 다름)
LOAD r1 000x
LOAD: 메모리를 빼오고 싶을 때(register에 address가불러옴)
STORE [레지스터][메모리주소]
레지스터에 있는 값을 메모리주소에 넣겠다
MOVE
로드 or 스토어
(r1)
괄호 하면 별 같은거. 주소를 가리키는거라서 주소값에 있는 값을 가져온다. 메모리 공간을 가르키거나 가져오거나. 메모리를 가르키는 것
9(r1)
r1+9 에 있는 값 가져오기(?)
문법
<명령> arg1, arg2....
mov는 load & store
Mov oper1 oper2
Mov source dest
source를 destination으로 옮긴다
맨 위 보면 D <- &S 따라서 주소를 가져옴
여기 답 이해 못함
왼쪽은 같은데(rotate되서) 오른쪽은 다름.
64-bit * 64-bit 해서 128-bit
메모리 읽기 read
메모리 쓰기 write
점프 jmp
종료 hlt
(추가로 call과 ret 이 있음)
이런식으로 if문의 바디를 goto문으로 쓸 수 있음
연산의 단계들이 오버래핑되면서 파이프라인이 고성능을 이룰 수 있는데(예를들어 이전 instruction의 산술 연산을 실행하면서 하나의 instruction을 fetching 하는 것처럼), 이걸 하기 위해서는 instructions이 언제 실행 될지 실행 시퀀스를 결정 해야한다.
conditional jump가 branch인데 이것만으로는 브랜치가 어디로 가야하는지 전부 브랜치 컨디션이 측정 되기 전까진 알 수가 없다. 그래서 프로세서는 'branch prediction logic'을 시도해서 점프를 할지 말지 예측한다.
while