๐ง ๋ฐ๋ณต๋ฌธ
๊ธฐ๊ณ์ด์๋ ๋ฐ๋ณต๋ฌธ์ ๋์๋๋ ์ธ์คํธ๋ญ์ ์ด ์์ต๋๋ค.
๊ทธ ๋์ ์กฐ๊ฑด๋ถ ํ ์คํธ์, ์ ํ ์ธ์คํธ๋ญ์ ์ ํจ๊ป ์ฌ์ฉํ์ฌ ๋ฐ๋ณต๋ฌธ์ ํํํฉ๋๋ค.
GCC ์ ๋ค๋ฅธ ์ปดํ์ผ๋ฌ๋ค์ ๋ฐ๋ณต๋ฌธ์ ๋ ๊ฐ์ ๊ธฐ๋ณธ ๋ฃจํ ํจํด์ ๊ธฐ์ดํ์ฌ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
๊ฐ์ฅ ๊ฐ๋จํ do-while๋ถํฐ ์์ํ์ฌ ๋ณด๋ค ๋ณต์กํ ๊ตฌํ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๋ฉฐ ๋ ๊ฐ์ง ํจํด์ ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ง do - while
do-while ๋ฌธ์ฅ์ ์ผ๋ฐ์ ์ธ ํํ๋ ์๋์ ๊ฐ์ต๋๋ค.
do {
body-statement
} while ( test-expr );
๋ฐ๋ณต๋ฌธ์ body-statement ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์คํํ๊ณ , test-expr ์ ๊ณ์ฐํ์ฌ ๊ทธ ๊ฒฐ๊ณผ๊ฐ 0์ด ์๋๋ผ๋ฉด ๋ฐ๋ณตํฉ๋๋ค.
body-statement ๋ ์ ์ด๋ ํ ๋ฒ ์คํ๋๋ค๋ ๊ฒ์ ์ฃผ๋ชฉํ๋ฉฐ,
ํด๋น ๋ฐ๋ณต๋ฌธ์ ์กฐ๊ฑด๋ฌธ + goto๋ฌธ์ผ๋ก ๋ฐ๊ฟ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
loop:
body-statement
t = test-expr;
if (t) goto loop;
์ค์ ์์๋ฅผ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค
long pcount_do(unsigned long x) {
long result = 0;
do {
result += x & 0x1;
x >>= 1;
} while (x);
return result;
}
์ด๋ฅผ goto ํํ๋ก ๋ฐ๊พธ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
long pcount_goto(unsigned long x) {
long result = 0;
loop:
result += x & 0x1;
x >>= 1;
if (x) goto loop;
return result;
}
์ด๋ฅผ ์ด์ ๋ธ๋ฆฌ์ด๋ก ๋ฒ์ญํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
pcount_goto:
movl $0, %eax # result = 0
.L2:
movq %rdi, $rdx # rdx = rdi(x)
andl $1, %edx # t = x & 0x1;
addq %edx, %eax # result += t(x & 0x1);
shrq $1, %rdi # x >>= 1 (unsigned๋ผ ๋
ผ๋ฆฌ ์ฌํํธ)
jne .L2 # x ๊ฐ 0์ด ์๋๋ฉด L2๋ก ์ด๋
rep; ret
๐ง while
while ๋ฌธ์ฅ์ ์ผ๋ฐ์ ์ธ ํํ๋ ์๋์ ๊ฐ์ต๋๋ค.
while ( test-expr )
body-statement
while๋ฌธ์ test-expr ์ ๋จผ์ ๊ณ์ฐํ์ฌ body-statement ๋ฅผ ์คํํ๊ธฐ ์ ์ ์ข ๋ฃ๋ ์ ์๋ค๋ ์ ์์ do-while๋ฌธ๊ณผ ๋ค๋ฆ ๋๋ค.
while๋ฌธ์ ๊ธฐ๊ณ์ด ์ฝ๋๋ก ๋ฒ์ญํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ผ๋ฉฐ,
์ด ๊ฐ์ด๋ฐ ๋ ๊ฐ์ ๋ฐฉ๋ฒ์ด GCC๊ฐ ์์ฑํ๋ ์ฝ๋์์ ์ด์ฉ๋ฉ๋๋ค.
๋ ๋ฐฉ๋ฒ ๋ชจ๋ do-while ๋ฃจํ์ ๊ตฌ์กฐ๊ฐ ๋์ผํ๊ณ , ์ด๊ธฐ ํ ์คํธ์ ๊ตฌํ๋ฐฉ๋ฒ์์๋ง ๋ค๋ฆ ๋๋ค.
โญ๏ธ ์ค๊ฐ์ผ๋ก ์ ํ (Jump to Middle)
๊ธฐ์กด while๋ฌธ์ ํํ
while ( test-expr )
body-statement
์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ค๊ฐ์ผ๋ก ์ ํ ์ ๋๋ค.
goto test; # ๋ฐ๋ก test๋ก ์ด๋ํฉ๋๋ค.
loop:
body-statement
test:
t = test-expr
if ( t ) goto loop;
done:
์์ ๊ฐ์ด loop์ ์ค๊ฐ์ผ๋ก ์ด๋ํ์ฌ ๊ฒ์ฌ๋ถํฐ ์งํํฉ๋๋ค.
์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
long pcount_while(unsigned long x) {
long result = 0;
while(x) {
result += x & 0x1;
x >>= 1;
}
return result;
}
์ด๋ฅผ ์ค๊ฐ์ผ๋ก ์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
long pcount_while(unsigned long x) {
long result = 0;
goto test;
loop:
result += x & 0x1;
x >>= 1;
test:
if (x) goto loop;
return result;
}
โญ๏ธ ์กฐ๊ฑดํ - do
์กฐ๊ฑดํ-do ๋ผ๊ณ ๋ถ๋ฅด๋ ๋ ๋ฒ์งธ ๋ฒ์ญ๋ฐฉ๋ฒ์
๋จผ์ ์ฝ๋๋ฅผ ์กฐ๊ฑด๋ถ ๋ถ๊ธฐ๋ฅผ ์ด์ฉํด์ ์ด๊ธฐ ํ ์คํธ๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ์ ๋ฃจํ๋ฅผ ๊ฑด๋๋ฐ๋๋ก ํ์ฌ
do-whille ๋ฃจํ๋ก ๋ฒ์ญํฉ๋๋ค.
GCC์ ๊ฒฝ์ฐ -O1 ์ต์ ์ ์ฌ์ฉํ์ฌ ์ปดํ์ผํ๋ ๊ฒฝ์ฐ ํด๋น ์ ๋ต์ ๋ฐ๋ฆ ๋๋ค.
์ด ๋ฐฉ๋ฒ์ ์ผ๋ฐ์ ์ธ while๋ฌธ์ ํํ๋ฅผ do-while ๋ฃจํ๋ก ๋ฒ์ญํ ๋, ๋ค์์ ํ ํ๋ฆฟ์ผ๋ก ํ์๋ ์ ์์ต๋๋ค.
๊ธฐ์กด while๋ฌธ์ ํํ
while ( test-expr )
body-statement
์ด๋ฅผ ์กฐ๊ฑดํ - do ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
t = test-expr;
if (!t) goto done;
do {
body-statement
} while( test-expr );
done:
์ด๋ ๋ค์ goto ์ฝ๋๋ก ๋ค์๊ณผ ๊ฐ์ด ๋ฒ์ญ๋ฉ๋๋ค.
t = test-expr;
if (!t) goto done;
loop:
body-statement
t = test-expr;
if (t) goto loop;
done:
๐ง For ๋ฃจํ
for ๋ฐ๋ณต๋ฌธ์ ์ผ๋ฐ์ ์ธ ์ ํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
for (init-expr; test-expr; update-expr)
body-statement
C์ธ์ด ํ์ค์์๋ ์ ๋ฐ๋ณต๋ฌธ์ด while ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ๋ ๋ค์์ ์ฝ๋์ ๋์ผํ ๋์์ ํ๋ค๊ณ ๊ธฐ๋ก๋์ด ์์ต๋๋ค.
(continue ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ ์ธ)
init-expr;
while ( test-expr ) {
body-statement
update-expr
}
ํ๋ก๊ทธ๋จ์ ๋จผ์ ์ด๊ธฐํ ์์์ธ init-expr์ ๊ณ์ฐํฉ๋๋ค
ํ ์คํธ ์กฐ๊ฑด์ธ test-expr์ ๊ณ์ฐํ๋ ๊ณณ์์ ๋ฃจํ์ ๋ค์ด๊ฐ๊ณ ,
ํ ์คํธ๊ฐ ์คํจํ๋ฉด ๋ฃจํ๋ฅผ ๋น ์ ธ๋์ค๋ฉฐ,
์ฑ๊ณตํ๋ค๋ฉด ๋ฐ๋ณต๋ฌธ body-statement๋ฅผ ์คํํ๋ฉฐ, update-expr์ ๊ณ์ฐํฉ๋๋ค
for๋ฃจํ์ ๋ํด ์์ฑ๋๋ ์ฝ๋๋ ์์์ ์ดํด๋ณธ while -> do-while ์ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ do-while๋ก ๋ฒ์ญ๋ฉ๋๋ค.
init-expr;
while ( test-expr ) {
body-statement
update-expr
}
(์กฐ๊ฑดํ - do ์ฌ์ฉ)
init-expr;
t = test-expr;
if (!t) goto done;
do {
body-statement
update-expr
} while( test-expr );
done:
ํท๊ฐ๋ฆฌ์ค ๊ฒ ๊ฐ์ ํ๋ฒ์ ๋ชจ์์ ํ์ธํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
โญ๏ธ do - while
do {
body-statement
} while ( test-expr );
์กฐ๊ฑด๋ฌธ + goto ๋ก ๋ฒ์ญ
loop:
body-statement
t = test-expr;
if (t) goto loop;
โญ๏ธ while
while ( test-expr )
body-statement
์ค๊ฐ์ผ๋ก ์ ํ
goto test; # ๋ฐ๋ก test๋ก ์ด๋ํฉ๋๋ค.
loop:
body-statement
test:
t = test-expr
if ( t ) goto loop;
done:
์กฐ๊ฑดํ - do
t = test-expr;
if (!t) goto done;
do {
body-statement
} while( test-expr );
done:
โญ๏ธ for
for (init-expr; test-expr; update-expr)
body-statement
while๋ก ๋ฒ์ญ
init-expr;
while ( test-expr ) {
body-statement
update-expr
}
์กฐ๊ฑดํ - do
init-expr;
t = test-expr;
if (!t) goto done;
do {
body-statement
update-expr
} while( test-expr );
done:
๐ง Switch
Switch๋ฌธ์ ์ ์ ์ธ๋ฑ์ค ๊ฐ์ ๋ฐ๋ผ ๋ค์ค๋ถ๊ธฐ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์ด๊ฒ์ ํ ์คํธํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์๊ฐ ๋ง์ ๊ฒฝ์ฐ์ ํนํ ์ ์ฉํฉ๋๋ค.
Switch๋ฌธ์ ์ฌ์ฉํ๋ฉด ์ ํ ํ ์ด๋ธ(Jump table)์ด๋ผ๋ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ ํจ์จ์ ์ผ๋ก ์กฐ๊ฑด์ ๋ฐ๋ฅธ ๋ถ๊ธฐ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์ ํ ํ ์ด๋ธ์ ํด๋น ํ ์ด๋ธ์ ์์ i๊ฐ, Switch๋ฌธ์ ๋์์ด i์ผ ๋ ํ๋ก๊ทธ๋จ์ด ์คํํด์ผ ํ๋ ๋์์ ๊ตฌํํ๋ ์ฝ๋ ๋ธ๋ก์ ์ฃผ์๊ฐ ๋๋ ๋ฐฐ์ด์ ๋งํฉ๋๋ค.
ํด๋น ์ฝ๋๋ ์ ํ ์ธ์คํธ๋ญ์ ์ ๋ชฉ์ ์ง๋ฅผ ์ฐพ์๋ด๊ธฐ ์ํด์ switch๋ฌธ์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ ํ ์ด๋ธ์ ๋ฐฐ์ด์ฒ๋ผ ์ฐธ์กฐํฉ๋๋ค.
์ ํ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ฉด switch๋ฌธ์ ์คํํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด ์ธ์ ๋ $O(1)์ ์๊ฐ$์ ๋ณด์ฅํฉ๋๋ค.
์ด๋ ๋ค๋จ๊ณ์ if-else๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ํจ์จ์ ์ ๋๋ค.
์ฐธ๊ณ - (https://stackoverflow.com/questions/2158759/case-vs-if-else-if-which-is-more-efficient)
โญ๏ธ ์์ ์ฝ๋
void switch_eg(long x, long n, long *dest) {
long val = x;
switch (x) {
case 100:
val *= 13;
break;
case 102:
val += 10;
/* Fall through */
case 103:
val += 11;
break;
case 104:
case 106:
val *= val;
break;
default:
val = 0;
}
*dest = val;
}
์ด๋ ํ์ฅํ C์์ ๋ค์๊ณผ ๊ฐ์ด ๋ฒ์ญ๋ฉ๋๋ค.
void switch_eg_impl(long x, long n, long *dest) {
/* Table of code pointers */
static void *jt[7] = { // Jump table
&&loc_A, &&loc_def, &&loc_B,
&&loc_C, &&loc_D, &&loc_def,
&&loc_D // D๊ฐ ์ค๋ณต ์ ์ (104์ 106์ด ๋์ผ ๋ถ๊ธฐ ์ฃผ์๋ก ์ฎ๊ธฐ์ด ๋๋ฌธ์ด๋ค)
};
unsigned long index = n - 100; // unsigned int๋ก ํด์ค ์ด์ ๋ `๋น ๋ฅธ ๊ฒฝ๊ณ ๊ฒ์ฌ`๋ฅผ ์ํด์์
๋๋ค.
long val;
// index๋ฅผ ๋น๋ถํธํ์ผ๋ก ํ์๊ธฐ์ 0 < index <= 6 ์ ๋ฒ์๋ฅผ ๊ฐ์ง๋์ง๋ฅผ ์กฐ๊ฑด๋ฌธ ํ๋ฒ์ผ๋ก ํ์ธ
if (index > 6)
goto loc_def; // default๋ก ์ด๋
/* Multiway branch */
goto *jt[index]; // Jump Table์ ์ฌ์ฉํ์ฌ O(1) ์๊ฐ์ ๋ถ๊ธฐ ์ฃผ์๋ก ์ด๋
/* ๋ถ๊ธฐ ์ฃผ์๋ค */
loc_A: /* Case 100: */
val = x * 13;
goto done;
loc_B: /* Case 102: */
val = x + 10;
goto done;
loc_C: /* Case 103: */
val = x + 11;
goto done;
loc_D: /* Case 104, 106: */
val = x * x;
goto done;
loc_def: /* default: */
val = 0;
done:
*dest = val;
}
์๋ณธ ์ฝ๋๋ case ๊ฐ์ผ๋ก 100, 102~104, 106์ ๊ฐ์ง์ง๋ง, Switch๋ฌธ์ ๋ณ์์ธ n์ ์์์ ์ ์๊ฐ ๋ ์ ์์ต๋๋ค.
์ปดํ์ผ๋ฌ๋ ๋จผ์ n์์ 100์ ๋นผ์ ๋ฒ์๋ฅผ 0์์ 6์ฌ์ด๋ก ๋ง๋ค์ด์ C ๋ฒ์ ์ฝ๋์์ index๋ผ๊ณ ํ๋ ์๋ก์ด ํ๋ก๊ทธ๋จ ๋ณ์๋ฅผ ์์ฑํ์์ต๋๋ค.
2์ ๋ณด์๋ก ํํ๋ ์์๋ฅผ ๋น๋ถํธํ ํ์๋ก ๋์์ํค๋ฉด ํฐ ์์ ๊ฐ์ด ๋๋ค๋ ์ฌ์ค์ ์ด์ฉํ์ฌ index๋ฅผ ๋น๋ถํธํ ๊ฐ์ผ๋ก ์ทจ๊ธํด์ ๋ถ๊ธฐ ๊ฐ๋ฅ์ฑ์ ๋จ์ํ์์ผฐ์ต๋๋ค.
๋ฐ๋ผ์ index ๊ฐ์ด 0~6 ๋ฒ์๋ฅผ ๋ฒ์ด๋๋์ง์ ๋ํ ํ๋จ์, 6๋ณด๋ค ํฐ์ง์ ๋ํด ํ๋จํ๋ ๋ฐฉ์์ผ๋ก ์ํํ ๊ฒ์ ๋๋ค.
๊ด๋ จํ ๋ด์ฉ์ ํด๋น ๊ธ ์ `๋น ๋ฅธ ๊ฒฝ๊ณ ๊ฒ์ฌ ๋ฐฉ๋ฒ`์ ํ์ธํด์ฃผ์ธ์ฉ :)
๋ ์ง์คํฐ๋ ๋ค์๊ณผ ๊ฐ์ด ํ ๋น๋ฉ๋๋ค.
%rdi - x
%rsi - n
%rdx - dest
switch_eg:
subq $100, %rsi # n = n - 100
cmpq $6, %rsi # n๊ณผ 6 ๋น๊ต
ja .L8 # ๋ง์ฝ n์ด 6๋ณด๋ค ํฐ ๊ฒฝ์ฐ L8 (log_def๋ก ์ด๋)
jmp *.L4(, %rsi, 8) # ๊ฐ์ ์ ํ ์ฌ์ฉ (n * 8 + L4)๋ก ์ด๋
.L3: # loc_A - Case 100
leaq (%rdi, %rdi, 2), %rax # result = x + 2x
leaq (%rdi, %rax, 4), %rdi # x = 4 * result + x ( == 13x)
jmp .L2 # goto done
.L5: # loc_B - Case 102
addq $10, %rdi # x = x + 10
.L6: # loc_C - Case 103
addq $11, %rdi # val = x + 11
.L7: # loc_D - Case 104, 106
imulq %rdi, %rdi # val = x * x
jmp .L2 # goto done
.L8: # loc_def - default
movl $0, %edi # val = 0
.L2: # done
movq %rdi, (%rdx) # *dest = val
ret
.setcion .rodata
.align 8 # Align address to multiple of 8
.L4: # Jump Table
.quad .L3 # Case 100 : loc_A
.quad .L8 # Case 101 : loc_def
.quad .L5 # Case 102 : loc_B
.quad .L6 # Case 103 : loc_C
.quad .L7 # Case 104 : loc_D
.quad .L8 # Case 105 : loc_def
.quad .L7 # Case 106 : loc_D
โญ๏ธ ์ ํ ํ ์ด๋ธ ๊ตฌ์กฐ
์๋์ ๊ฐ์ ์ ํ ํ ์ด๋ธ์ ์์๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ ํ ํ ์ด๋ธ์ ๊ฐ ํ๊ฒ์ ์ฃผ์์ด๋ฏ๋ก ํ๊ฒ๋ณ๋ก 8๋ฐ์ดํธ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค.
๋ํ ์ ํ ํ ์ด๋ธ์ ์์์ฃผ์๋ .L4 ์ ๋๋ค.
์ ํํ๊ธฐ ์ํด์๋ ์ง์ ์ ํ ํน์ ๊ฐ์ ์ ํ๋ฅผ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
์ง์ ์ ํ : jmp .L8
์ ํ ๋์์ ๋ ์ด๋ธ์ด๋ฉฐ, .L8 ๋ก ํ์๋ฉ๋๋ค.
๊ฐ์ ์ ํ : jmp *.L4(, %rdi, 8)
์ ํ ํ ์ด๋ธ์ ์์ : .L4
์ฃผ์์ด๋ฏ๋ก 8์ ๋ฐฐ์๋ก ์ฆ๊ฐํด์ผ ํฉ๋๋ค.
์ ํ ํ๊ฒ์ ์ ํจ์ฃผ์ .L4 + x * 8 ๋ก๋ถํฐ ์ป์ด์ง๋๋ค. ( $0 \leq x leq 6$ ์ ๋ํด์๋ง ์ฑ๋ฆฝํฉ๋๋ค. )
'๐ฅ Computer Science > ์์คํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์คํ ํ๋ก๊ทธ๋๋ฐ] 2022 BombLab(๋ฐค๋ฉ) ์์ธ๋ถ์ (0) | 2022.10.24 |
---|---|
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ด์ ๋ธ๋ฆฌ์ด[4] - ํ๋ก์์ (0) | 2022.10.24 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ด์ ๋ธ๋ฆฌ์ด[2] - ์กฐ๊ฑด๋ฌธ (2) | 2022.10.12 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] ์ด์ ๋ธ๋ฆฌ์ด [1] (2) | 2022.10.10 |
[์์คํ ํ๋ก๊ทธ๋๋ฐ] - 2022๋ ๋ Datalab (0) | 2022.10.04 |