Machine Level Programming : Control

임승섭·2023년 4월 20일
0

Computer Systems

목록 보기
2/7

Control Flow 제어문

extern void op1(void);
extern void op2(void);

void decision(int x) {
	if (x) {
    	op1();
    }
    else {
    	op2();
    }
}
decision :
	subq	$8, %rsp
    test1	%edi, %edi
    je		.L2
    call 	op1
    jmp		.L1
.L2 :
	call	op2
.L1 :
	addq	$8, %rsp
    ret

Processor State

(Information about currently executing program)

  • Temporary data (%rax, ...)
  • Location of runtime stack (%rsp, ...)
  • Location of current code control point (%rip, ...)
  • Status(Flag) of recent tests (CF, ZF, SF, OF)

Condition Codes (Implicit Setting)

addq src, dst <=> t = a + b

  • CF : carry flag (for unsigned)
    : 가장 최근 연산에서 MSB로부터 받아 올림이 발생한 것 표시. unsigned 연산에서 오버플로우 검출할 때 사용
    if (t < a)

  • ZF : zero flag
    : 가장 최근 연산의 결과가 0인 것을 표시
    if t == 0

  • SF : sign flag (for signed)
    : 가장 최근 연산이 음수를 생성한 것을 표시
    MSB가 1이면 음수라고 판단한다.
    if t < 0

  • OF : overflow flag (for signed)
    : 가장 최근 연산이 양수/음수의 2의 보수 오버플로우를 발생시킨 것을 표시
    if (a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)

Compare Instruction

cmp a, b

  • Computes b - a (just like sub)
  • Sets condition codes based on result.
  • used for if (a < b) { ...}

Test Instruction

test a, b

  • Computes a&b (just like and)

  • Sets condition codes (only SF and ZF) based on result

  • common use : test %rX, %rX to compare %rX to zero

  • common use 2 : test %rX, %rY to test if any of 1-bits in %rY are also 1 in %rX (or vice versa)


Conditional operations

Jump instrucion

  • jump to different part of code depending on condition codes
jXConditionDescription
jmp1Unconditional
jeZFEqual / Zero
jne~ZFNot Equal / Not Zero
jsSFNegative
jns~SFNonnegative
jgGreater
jgeGreater or Equal
jlLess
jleLess or Equal
jaAbove (unsigned)
jbbelow (unsigned)

Set instruction

  • set low-order byte of destination to 0 or 1 based on combinations of condition codes
SetXConditionDescription
seteZFEqual / Zero
setne~ZFNot Equal / Not Zero
setsSFNegative
setns~SFNonnegative
setgGreater
setgeGreater or Equal
setlLess
setleLess or Equal
setaAbove (unsigned)
setbBelow (unsigned)
  • C code
int gt(long x, long y) {
	return x > y;
}
  • Assembly
x in %rdi, y in %rsi, return value in %rax

cmp		%rsi, %rdi		// Compare x : y	 (y - x)
setg	%al				// Set when >
movzbl %al, %eax		// Zero rest of %rax
  • C code
long absdiff(long x, long y) {
	long result;
    if (x > y) 
    	result = x - y;
    else
    	result = y - x;
    return result;
}
  • Assembly
x in %rdi, y in %rsi
absdiff :
	comp %rsi, %rdi		// Compare x : y
    jle .L4
    movq %rdi, %rax		// %rax = x
    subq %rsi, %rax		// $rax = %rax - %rsi  (x - y)
    ret
.L4 :					// x <= y
	movq %rsi, %rax		// %rax = y
    subq %rdi, %rax		// %rax = %rax - %rdi (y - x)
    ret

Loops 반복문

  • C code
long pcount_do(unsigned long x) {
	long result = 0;
    do {
    	result += x & 0x1;
        x >> 1;
    } while (x);
    
    return result;
}
  • Goto version
long pcount_goto(unsigned long x) {
	long result = 0;
    loop :
    	result += x & 0x1;
        x >> 1;
    if (x) goto loop;
    
    return result;
}
  • Assembly
x in %rdi, result in %rax

	movl	$0, %rax	// result = 0
.L2 :
	movq	%rdi, %rdx	// %rdx = x
    andl	$1, %rdx	// %rdx = x & 1.
    addq	%rdx, %rax	// result += x&1
    shrq	%rdi		// x >>= 1
    jne		.L2			// if (x) goto loop
    rep; ret

General "while" translation

  • C code
long pcount_while(unsigned long x) {
	long result = 0;
    while (x) {
    	result += x & 0x1 ;
        x>> 1;
    }
    return result;
}
  • #1. Jump to Middle
long pcount_goto_jtm(unsigned long x) {
	long result = 0;
    goto test
    
   loop :
    result += x & 0x1;
    x >> 1;
   
   test :
    if (x) goto loop;
    return result;
  • #2. Do-While Version
long pcount_goto_dw(unsigned long x) {
	long result = 0;
    if (!x) goto done;
   
   loop :
    result += x & 0x1;
    x >>= 1;
    if (x) goto loop;
   
   done:
    return result;
}

Swith 문

long switch_eg(long x, long y, long z) {
	long w = 1;
    
    switch(x) {
    	case 1 :
        	w = y * z;
            break;
        case 2 :
        	w = y / z;
            /* Fall Throuh */
        case 3 :
        	w += z;
            break;
        case 5 :
     	case 6 :
        	w -= z;
            break;
        default :
        	w = 2;
        }
        
        return 2;
}
x in %rdi, y in %rsi, z in %rdx, return value in %rax

//setup
swtich_eq :
	movq	%rdx, %rcx	// %rcx = z
    cmpq	$6, %rdi	// x : 6 비교
    ja		.L8			// 6보다 크면 default값을 가지게 한다.
    
    jmp		* .L4(, %rdi, 8) // goto *JTap[x]. Indirect Jump
<jump table>
.section .rodata
		 .align 8
         
.L4
		 .quad	.L8	// x = 0
         .quad	.L3 // x = 1
         .quad	.L5 // x = 2
         .quad	.L9 // x = 3
         .quad	.L8 // x = 4
         .quad	.L7 // x = 5
         .quad	.L7 // x = 6


Jumping
- direct : **jmp .L8**	
     - Jump target is denoted by label **.L8**


- indirect : **jmp *.L4(, %rdi, 8)**
   - Start of jump table : .L4
   - Must scale by factor of 8 (addresses are 8 bytes)
   - Fetch target from effective Address .L4 + x*8
   - only for 0 <= x <= 6
   

나머지 이어서
.L3 :
movq %rsi, %rax // %rax = y
imulq %rdx, %rax // %rax = y * z
ret

.L5 :
movq %rsi, %rax // %rax = y
cqto
idivq %rcx // y/z
jmp .L6 // goto merge

.L9 :
movl $1, %rax // %rax = 1

.L6 :
addq %rcx, %rax // %rax += z
ret

.L7 :
movl $1, %rax // %rax = 1
subq %rdx, %rax // %rax -= z
ret

.L8 :
movl $2, %rax // %rax = 2
ret









     

0개의 댓글