본문 바로가기

학교/시스템 프로그래밍

(7)
Control Flow cpu는 한 번에 하나의 명령어만 수행할 수 있음 이 명령어의 순서를 Control Flow라고 한다. Control Flow의 전환 프로그램 상태 changing - branch로 점프 - return call 시스템 상태의 changing - 디스크나 네트워크로부터 데이터가 왔을 때, - 0으로 나눌 때 - 사용자가 커맨드에서 ctrl+c를 누를 때 - 시스템 타이머 만료(일정주기 마다 만료됨) 이런 예외를 처리하기 위해, 프로그램은 OS에 제어권을 넘긴다. (시스템 상태 변화는 usermode에서 해결이 불가능하다.) Exception 위에서 시스템 상태의 chaingin이 일어나는 상황을 예외(Exception)이라고 한다. 에러가 처리되고 나면, 원래 실행했던 다음 명령어로 이동시킨다. Arm에..
Signal 시스템에서 상호작용(interaction) 종류 1. 어셈 : 명령어 사이의 상호작용 2. 프로시저 호출 : 함수 사이의 상호작용 3. Linking : obj 파일간의 상호작용 4. Exception : OS와의 상호작용 (application -> OS) 5. signal : kernel과의 상호작용 (kernel -> application) SIGNAL이란? 시스템에서 특정 유형의 이벤트가 발생했을 때, process에게 알려주는 신호(signal) - Exception 및 interrupt와 유사 - kernel로 부터 받는 메시지 - 프로세스끼리 보낼 수 있음 - 시그널 유형은 integer 값으로 분류 (1~31) - 시그널에서 유일한 정보는 시그널 유형과, 도착했다는 신호이다. Send SI..
PC, LR, SP sp sp는 스택 포인터로, 변수는 sp를 기준으로 생성, 접근된다. 마지막에는 이렇게, 8바이트를 사용했으니, 그만큼 8바이트를 더해주고, sp에 더한 값을 넣는다. 보통은 이걸 스택을 정리해준다 라고 한다. lr, pc lr은 Return address가 담겨있는 부분이다. pc는 현재 실행중인 명령어의 위치이다. 1~10000까지 더하는 코드다 11줄의 bl sum 에 bp를 찍고 실행한 disassemble 창이다. pc는 다음 실행할 명령어인 0x808c를 가리키고, 아직은 main 함수 내여서 돌아갈 주소가 없으니, lr은 0x0이다. sum 브랜치가 종료되면 loop브랜치를 마저 실행해야 하니, bl sum의 다음 명령어인, 0x8090 (loop+16)의 값을 저장하고, pc는 그냥 실행할..
LDR / STR Indexing 기본 사용방법 LDR | STR rd, [rn], [] { ! } 그냥 이걸 보기 편하게 하면 포인터와 &라고 보면 된다. 여기서 대략적인 사용법은 봤으니 다음 걸 설명한다. LDR R0, [ R1, #1 ] => R0 = R1[ 1 ] => R1 + 1 과 같다. LDR R0, [ R1, R2, LSL #2 ] => R0 = R1[ R2 * 4 ] 와 같다. 마찬가지로 STR을 보면 STR R0, [ R1, R2, LSL #2 ] => R1[ R2 * 4 ] = R0 이다. 간단한 예시를 보자. msg를 0x1234로 초기화 한뒤, ldr로 가져오는 코드다. 간단히 말해서, r1은 r0[1] 이므로, 0x1234에서 0x12를 가져오고, r2는 r0[2] 이지만, r0[2]은 0이어서 0을 가져온다. ..
section .text read-only section 코드 영역이라고도 불리며, 상수 및 실행 코드인 기계어 코드들이 담겨 있다. .end 프로그램이 끝나는 부분. 이후의 코드는 무시된다. .data 말 그대로 데이터 영역. global 변수와 static 변수가 여기에 들어간다. 다만, static은 공간만 할당되고, static 변수가 있는 함수가 실행될 때 초기화 된다. 프로그램이 시작할 때 할당되고, 종료될 때 반환된다. 여기서 초기화된 데이터는 .data에 들어가고, 초기화되지 않은 변수는 .bss 에 들어간다. 예시 코드를 보면 .text .global _start _start: adr r4, a ldr r0, [r4] adr r4, b ldr r1, [r4] add r3, r0, r1 @ a + b a..
shift 연산자 1. lsl, lsr lsl부터 보자. 다만, 플래그 값을 보기 위해선 명령어에 S를 붙여야 한다. lsl 해주고 왜 안되나 한참 생각했네.. 1 .global _start 2 _start: 3 mov r0, #0x7FFFFFFF 4 lsls r0, #1 5 lsls r0, #1 @ 여기까지만 cpsr이 변한다. 6 lsls r0, #1 7 lsls r0, #1 8 lsls r0, #1 9 b exit 10 11 exit: 12 mov r0, #0 13 mov r7, #1 14 swi 0 r0에 signed int의 최대값을 넣은 뒤, 왼쪽으로 shift 연산을 할 때마다 레지스터 상태를 볼 것이다. 여기서 0x80000000 값이 더해진 걸 볼 수 있다. 이는 이진수로 1000 0000 0000 000..
1. LDR/STR/ADR, 논리 연산 1. LDR/STR 레지스터 데이터를 전송하는 두 가지 명령어 : LDR, STR LDR : 메모리값를 레지스터로 복사한다. STR : 레지스터의 값을 메모리에 저장 EX) LDR r1, [r2] @ r2의 메모리 주소를 r1에 저장. 두 번째 인자가 레이블 같은 상수가 아닌, 레지스터라면, []로 감싸준다. STR r3, [r4] @ r3의 값을 r4가 가리키는 메모리 주소에 저장 C언어로 치면 LDR은 int r2 = 1; int *r1 = &r2; // r1 : r2가 저장된 메모리 주소 값 라 볼 수 있고, STR은 *r1 = 2 // r1이 가리키고 있는 메모리 주소 값에 2를 씀 라고 볼 수 있다. .global _start _start: ldr r1, =array@ *r1 = &array m..