반응형
Control: Condition codes
Processor State (x86-64, Partial)
- x86-64에는 16개의 register가 존재
- rsp는 stack을 나타내는 레지스터
- rip는 명령문을 가리키는 레지스터
- condition codes는 주어진 4개의 1 bit flag 말고도 8개가 존재
Condition Codes (Implicit Setting)
- CF : 너무 큰 수의 연산에서 MSB 비트에서 올림이 발생한 경우
- ZF : 연산으로 인해 0의 값이 발생한 경우
- SF : 두 수의 연산으로 인해 음수의 값이 발생한 경우
- OF : 연산에서 overflow가 발생한 경우(positive overflow & negative overflow)
Condition Codes (Explicit Setting: Compare)
- 비교 연산은 뺄셈 연산 이후 결과를 사용하지는 않는다
Condition Codes (Explicit Setting: test)
- Test 연산은 보통 하나의 수를 가지고 연산한다 (ex. testq %rax %rax)
- 값이 같으면 1
Reading Condition Codes
- 4개의 flag bit 조합에 따라 연산자들의 대소 관계가 결정된다
- 위의 조합들을 쉽게 사용할 수 있도록 setX instruction이 존재한다
Reading Condition Codes (Cont.)
- cmpq 연산자는 순서를 바꾼다
- setg : Greater (signed)
- movzbl ( move zero extension byte to long ) : 다른 레지스터의 값을 복사하고 왼쪽 비트를 모두 0으로 초기화
Conditional Branches
Jumping
- C언어의 goto문과 같은 역할을 한다
Conditional Branch Example (Old Style)
- colon은 label을 나타내는데 쓰인다 (jump가 어디에 land할 지)
- %rax를 사용한 이유는 그냥 common이라서
Expressing with Goto Code
General Conditional Expression Translation (Using Branches)
Using Conditional Moves
- 아주 가끔, 성공의 경우와 실패의 경우 모두 미리 계산해두고 그 결과에 따라 미리 계산해둔 값을 반환하는게 빠른 경우도 있다고 한다
Conditional Move Example
- 미리 계산해두고 반환하는 방식
- cmovle ( c move less greater )
Bad Cases for Conditional Move
- 두 예상 결과 모두 복잡한 연산일 때
- NPE 발생 가능한 경우
- 두 연산으로 인해 side effect가 발생 가능
Loops
"Do - While" Loop Example
- do while 문은 어셈블리에서 go to를 사용하게 된다
General "Do-While" Translation
General "While" Translation #1
- -Og 설정을 사용하면 gcc가 위의 상황처럼 while 구문을 해석한다
General "While" Translation #2
- -O1 설정을 사용하면 gcc가 위의 상황처럼 while 구문을 해석한다
"For" Loop Form
"For" Loop -> While Loop
Switch Statements
Switch Statement Example
- switch 구문의 단점들..
- 기계어에서는 if else 구문의 연속과는 다르게 해석한다
Jump Table Structure
- case 구문이 많아질 수록 Jump Table 배열의 크기가 커진다
- 배열의 인덱스를 이용해 해당 코드 블럭으로 진입 가능
Switch Statement Example
- cmpq 명령어에서 6이 나온 이유는 case 6이 가장 높은 구문이기 때문이다
- ja (jump above : unsigned comparison) 명령어는 default case로 향한다
- jg (jump greater : signed comparison) 명령어가 아닌 ja 명령어를 사용했기 때문에 6보다 큰 case 뿐만 아니라 0보다 작은 case에서도 default로 향한다
Code Blocks
- break 구문은 별도의 명령어 없이 바로 return 한다
- case 2에서는 case 3의 연산마저 해버린다
Summary
추가 질문
1. jump table은 컴파일러가 만드는가?
- 그렇다
2. case [음수] 인 경우에는 array indexing을 어떻게 하는가?
- bias를 더해서 항상 최소값이 0이 되도록 한다
- 마찬가지로 큰 양수인 경우에도 bias를 빼준다
3. case 0 , case 1,000,000 인 경우에는 두 경우를 위해서 백만개의 entry table이 생성되는가?
- 그렇다
- 이런 경우에는 if, else if 구문을 사용하는 것이 낫다
- 다만, 백만번을 순차적으로 도는 것은 아니라 이진 트리를 이용한다면 O(logn) 일 것이다
4. sparse한 경우에는?
- 컴파일러가 적절히 모은다
반응형
'Computer Science Lectures > Introduction to Computer Systems - CMU' 카테고리의 다른 글
Lecture 08: Machine-Level Programming 4: Data (0) | 2022.10.31 |
---|---|
Lecture 07: Machine-Level Programming 3: Procedures (0) | 2022.10.25 |
Lecture 05: Machine-Level Programming 1: Basics (0) | 2022.10.19 |
Lecture 04: Floating Point (0) | 2022.10.18 |
Lecture 03: Bits, Bytes, and Integers (cont.) (0) | 2022.10.11 |