Computer Science Lectures/Introduction to Computer Systems - CMU

Lecture 06: Machine-Level Programming 2: Control

오렌지색 귤 2022. 10. 24. 23:50
반응형

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한 경우에는?
- 컴파일러가 적절히 모은다

 

반응형