Contents
- 1. before
- 2. ๊ฐ์
- 3. ์์
- 4. ์ฐ์ ๊ณ์ฐ, ๋น๊ต, ๋ฐ๋ณต
- 5. ํจ์(subroutine)
- 6. ์คํ ์ฌ์ฉํ๊ธฐ
- 7. ์ง์ญ๋ณ์(local variable) ๊ณต๊ฐ ํ ๋นํ๊ธฐ
- 8. ํ๋ผ๋ฏธํฐ ์ ๋ฌ๊ณผ ๊ฐ ๋ฐํ
- 9. C์ ์ด์ ๋ธ๋ฌ ์๊ธฐ
- 10. GNU C๊ฐ ๋ง๋๋ ์ด์ ๋ธ๋ฌ ์ถ๋ ฅ
- 11. ์์คํ ํธ์ถ(system call)
- 12. ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฆฌ ํ๋ก๊ทธ๋๋ฐ
- 13. ์ฐ์ต๋ฌธ์
1. before ¶
์๋ฌธ ์ถ์ฒ : http://blog.naver.com/webman21/18265245
๋ด์ฉ์ด ๋ณผ๋งํด์ ์ฌ๋ฆผ. ํ .. ใ ก.ใ ก ์ด์ copy paste ๋ ๊ท์ฐฎ๊ตฌ๋;; ํค๋ณด๋์ ์น๊ธฐ๊ฐ ์ซ๋ค.
๋ด์ฉ์ด ๋ณผ๋งํด์ ์ฌ๋ฆผ. ํ .. ใ ก.ใ ก ์ด์ copy paste ๋ ๊ท์ฐฎ๊ตฌ๋;; ํค๋ณด๋์ ์น๊ธฐ๊ฐ ์ซ๋ค.
2. ๊ฐ์ ¶
๋ง์ดํฌ๋ก์ปดํจํฐ ์์คํ
์ ๊ตฌ์ฑ์์๊ฐ ๋ฌด์์ธ๊ฐ? ๋ง์ดํฌ๋ก์ปดํจํฐ ์์คํ
์ ๋ง์ดํฌ๋กํ๋ก์ธ์ ์ฅ์น (microprocessor unit, MPU), ๋ฒ์ค ์์คํ
, ๋ฉ๋ชจ๋ฆฌ ํ์์์คํ
, ์
์ถ๋ ฅ ํ์์์คํ
, ๋ชจ๋ ๊ตฌ์ฑ์์๋ค๊ฐ์ ์ธํฐํ์ด์ค๋ก ๊ตฌ์ฑ๋๋ค. ์ ํ์ ์ธ ๋๋ต์ด๋ค.
์ด๋ ํ๋์จ์ด๋ง์ ๊ณ ๋ คํ ๊ฒ์ด๋ค. ๋ชจ๋ ๋ง์ดํฌ๋ก์ปดํจํฐ ์์คํ
์ ํ๋์จ์ด ๊ตฌ์ฑ์์๋ค์ ์์
์ ์ง์ํ ์ํํธ์จ์ด๊ฐ ํ์ํ๋ค. ์ปดํจํฐ ์ํํธ์จ์ด๋ ์์คํ
์ธก(์์คํ
์ํํธ์จ์ด)๊ณผ ์ฌ์ฉ์์ธก(์ฌ์ฉ์ ์ํํธ์จ์ด)์ผ๋ก ๊ตฌ๋ถํ ์ ์๋ค.
ํ๋ก๊ทธ๋จ์ ์คํํ๊ธฐ์ํด ํ์ํ ํจ์๋ค์ ๋ชจ์๋ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ๋ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ฉ์ ์ํํธ์จ์ด์ ํฌํจ๋๋ค.
๊ณ ๊ธ์ธ์ด ๋ณํ๊ธฐ, ์ด์
๋ธ๋ฌ, ํธ์ง๊ธฐ, ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ๋ง๋๋ ์์
์ ๋๋ ํ๋ก๊ทธ๋จ๋ค์ด ์์คํ
์ํํธ์จ์ด์ ์ํ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ ํ๋ก๊ทธ๋๋ฐ์๋ ๊ธฐ๊ณ์ด, ์ด์
๋ธ๋ฆฌ์ด, ๊ณ ๊ธ์ธ์ด ์ธ ๋จ๊ณ๊ฐ ์์์ ์๋ค.
๊ธฐ๊ณ์ด ํ๋ก๊ทธ๋จ์ ์ปดํจํฐ๊ฐ ์ดํดํ๊ณ ์ง์ ์คํํ ์ ์๋ ํ๋ก๊ทธ๋จ์ด๋ค. ์ด์
๋ธ๋ฆฌ์ด ๋ช
๋ น์ด๋ ๊ธฐ๊ณ์ด ๋ช
๋ น์ด์ ๋ณดํต ์ผ๋์ผ ๊ด๊ณ๋ก ๋์ํ์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ฝ๊ฒ ์ดํดํ ์ ์๋ ๋ฌธ์์ด์ ์ฌ์ฉํ๋ค. ๊ณ ๊ธ์ธ์ด ๋ช
๋ น์ด๋ ์์ด์ ๋งค์ฐ ๊ฐ๊น์์ ํ๋ก๊ทธ๋๋จธ๊ฐ ์๊ฐํ๋ ๋ฐฉ์๊ณผ ์์ฐ์ค๋ฝ๊ฒ ๋์ํ๋ค. ๊ฒฐ๊ตญ ์ด์
๋ธ๋ฆฌ์ด๋ ๊ณ ๊ธ์ธ์ด ํ๋ก๊ทธ๋จ์ ๋ณํ๊ธฐ๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ํด ๊ธฐ๊ณ์ด๋ก ๋ณํ๋์ผ ํ๋ค. ์ด ๋ณํ๊ธฐ๋ฅผ ๊ฐ๊ฐ ์ด์
๋ธ๋ฌ(assembler), ์ปดํ์ผ๋ฌ(compiler) ํน์ ์ธํฐํ๋ฆฌํฐ(interpreter)๋ผ๊ณ ํ๋ค.
C/C++๊ฐ์ ๊ณ ๊ธ์ธ์ด์ ์ปดํ์ผ๋ฌ๋ ๊ณ ๊ธ์ธ์ด๋ฅผ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ก ๋ณํํ ์ ์๋ค. GNU C/C++ ์ปดํ์ผ๋ฌ์ -S ์ต์
์ ํ๋ก๊ทธ๋จ ์์ค์ ํด๋นํ๋ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ์์ฑํ๋ค. ๋ฐ๋ณต, ํจ์ ํธ์ถ, ๋ณ์ ์ ์ธ๊ณผ ๊ฐ์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๊ฐ ์ด์
๋ธ๋ฆฌ์ด๋ก ์ด๋ป๊ฒ ๋์ํ๋์ง ์๋ฉด C ๋ด๋ถ๋ฅผ ์ดํดํ๊ธฐ ์ฝ๋ค. ์ด ๊ธ์ ์ดํดํ๊ธฐ์ํด์๋ ์ปดํจํฐ๊ตฌ์กฐ์ Intel x86 ์ด์
๋ธ๋ฆฌ์ด์ ์ต์ํด์ผ ํ๋ค.
3. ์์ ¶
๋จผ์ hello world๋ฅผ ์ถ๋ ฅํ๋ ๊ฐ๋จํ C ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ณ , -S ์ต์
์ผ๋ก ์ปดํ์ผํ๋ค. ์
๋ ฅํ์ผ์ ๋ํ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ์ป์ ์ ์๋ค. GCC๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฅ์ `.c'๋ฅผ `.s'๋ก ๋ณ๊ฒฝํ์ฌ ์ด์
๋ธ๋ฌํ์ผ๋ช
์ ์ง๋๋ค. ์ด์
๋ธ๋ฌํ์ผ ๋์ ๋ช์ค์ ํด์ํด๋ณด์.
80386 ์ด์ ํ๋ก์ธ์์๋ ๋ง์ ๋ ์ง์คํฐ์ ๋ช
๋ น์ด, ์ฃผ์์ง์ ๋ฐฉ๋ฒ์ด ์๋ค. ๊ทธ๋ฌ๋ ๊ฐ๋จํ ๋ช
๋ น์ด ๋ช๊ฐ๋ง ์ข ์์๋ GNU ์ปดํ์ผ๋ฌ๊ฐ ๋ง๋๋ ์ฝ๋๋ฅผ ์ถฉ๋ถํ ์ดํดํ ์ ์๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ด์
๋ธ๋ฆฌ์ด ๋ช
๋ น์ด๋ ๋ผ๋ฒจ(label), ์ฐ์๊ธฐํธ(mnemonic), ์ฐ์ฐ์(operand)๋ก ๊ตฌ์ฑ๋๋ค. ์ฐ์ฐ์ ํ์๋ฐฉ๋ฒ์์ ์ฐ์ฐ์์ ์ฃผ์์ง์ ๋ฐฉ์์ ์ ์ ์๋ค. ์ฐ์๊ธฐํธ๋ ์ฐ์ฐ์์ ์ ์ฅ๋ ์ ๋ณด์ ์์
์ ํ๋ค. ์ฌ์ค ์ด์
๋ธ๋ฆฌ์ด ๋ช
๋ น์ด๋ ๋ ์ง์คํฐ์ ๋ฉ๋ชจ๋ฆฌ์์น์ ์์
์ ํ๋ค. 80386๊ณ์ด์ eax, ebx, ecx ๋ฑ์ (32๋นํธ) ๋ฒ์ฉ๋ ์ง์คํฐ๋ฅผ ๊ฐ์ง๋ค. ๋ ๋ ์ง์คํฐ, ebp์ esp๋ ์คํ์ ์กฐ์ํ ๋ ์ฌ์ฉํ๋ค. GNU Assembler (GAS) ๋ฌธ๋ฒ์ผ๋ก ์์ฑํ ์ ํ์ ์ธ ๋ช
๋ น์ด๋ ๋ค์๊ณผ ๊ฐ๋ค:
์ด ๋ช
๋ น์ด๋ eax ๋ ์ง์คํฐ์ ๊ฐ 10์ ์ ์ฅํ๋ค. ๋ ์ง์คํฐ๋ช
์์ `%'์ ์ง์ ๊ฐ(immediate value) ์์ '$'๋ ํ์ ์ด์
๋ธ๋ฌ ๋ฌธ๋ฒ์ด๋ค. ๋ชจ๋ ์ด์
๋ธ๋ฌ๊ฐ ์ด๋ฐ ๋ฌธ๋ฒ์ ๋ฐ๋ฅด๋ ๊ฒ์ ์๋๋ค.
๋ชฉ๋ก 1์ first.s ํ์ผ์ ์ ์ฅํ ์ฐ๋ฆฌ์ ์ฒซ๋ฒ์งธ ์ด์
๋ธ๋ฆฌ์ด ํ๋ก๊ทธ๋จ์ด๋ค.
#๋ชฉ๋ก 1
cc first.s ๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด ์ด ํ์ผ์ ์ด์
๋ธํ๊ณ ๋งํฌํ์ฌ a.out์ ๋ง๋ ๋ค. GNU ์ปดํ์ผ๋ฌ ์๋จ cc๊ฐ `.s' ํ์ฅ์๋ฅผ ์ด์
๋ธ๋ฆฌ์ด ํ์ผ๋ก ์ธ์ํ์ฌ, ์ปดํ์ผ๋จ๊ณ๋ฅผ ์๋ตํ๊ณ ์ด์
๋ธ๋ฌ์ ๋ง์ปค๋ฅผ ๋ถ๋ฅธ๋ค.
ํ๋ก๊ทธ๋จ์ ์ฒซ๋ฒ์งธ ์ค์ ์ฃผ์์ด๋ค. ์ด์
๋ธ๋ฌ ์ง์์ด .globl์ ์ฌ๋ณผ main์ ๋ง์ปค๊ฐ ๋ณผ ์ ์๋๋ก ๋ง๋ ๋ค. ๊ทธ๋์ผ main์ ํธ์ถํ๋ C ์์๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ๋ก๊ทธ๋จ๊ณผ ๊ฐ์ด ๋งํฌํ๋ฏ๋ก ์ค์ํ๋ค. ์ด ์ค์ด ์๋ค๋ฉด ๋ง์ปค๋ 'undefined reference to symbol main' (์ฌ๋ณผ main์ ๋ํ ์ฐธ์กฐ๊ฐ ์ ์๋์ง์์)์ ์ถ๋ ฅํ๋ค (ํ๋ฒ ํด๋ด๋ผ). ํ๋ก๊ทธ๋จ์ ๋จ์ํ ๋ ์ง์คํฐ eax์ ๊ฐ 20์ ์ ์ฅํ๊ณ ํธ์ถ์์๊ฒ ๋ฐํํ๋ค.
~cpp movl $10, %eax
~cpp .globl main main: movl $20, %eax ret
4. ์ฐ์ ๊ณ์ฐ, ๋น๊ต, ๋ฐ๋ณต ¶
๋ค์ ๋ชฉ๋ก 2 ํ๋ก๊ทธ๋จ์ eax์ ์ ์ฅ๋ ๊ฐ์ ๊ณ์น(factorial)์ ๊ณ์ฐํ๋ค. ๊ฒฐ๊ณผ๋ฅผ ebx์ ์ ์ฅํ๋ค.
#๋ชฉ๋ก 2
L1๊ณผ L2๋ ๋ผ๋ฒจ์ด๋ค. ์ ์ดํ๋ฆ์ด L2์ ๋๋ฌํ๋ฉด, ebx๋ eax์ ์ ์ฅ๋ ๊ฐ์ ๊ณ์น์ ์ ์ฅํ๊ฒ ๋๋ค.
~cpp .globl main main: movl $5, %eax movl $1, %ebx L1: cmpl $0, %eax //eax์ ์ ์ฅ๋ ๊ฐ๊ณผ 0์ ๋น๊ต je L2 //0==eax ์ด๋ฉด L2๋ก ๊ฑด๋๋ (je - jump if equal) imull %eax, %ebx // ebx = ebx*eax decl %eax //eax ๊ฐ์ jmp L1 // L1์ผ๋ก ๋ฌด์กฐ๊ฑด ๊ฑด๋๋ L2: ret
5. ํจ์(subroutine) ¶
๋ณต์กํ ํ๋ก๊ทธ๋จ์ ๋ง๋ค๋ ์ฐ๋ฆฌ๋ ํด๊ฒฐํ ๋ฌธ์ ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ํ ๋๋ง๋ค ํธ์ถํ ํจ์๋ฅผ ์์ฑํ๋ค. ๋ชฉ๋ก 3์ ์ด์
๋ธ๋ฆฌ์ด ํ๋ก๊ทธ๋จ์ ํจ์ ํธ์ถ๊ณผ ๋ฐํ์ ๋ณด์ฌ์ค๋ค.
#๋ชฉ๋ก 3
call ๋ช
๋ น์ด๋ ์คํ์ ํจ์ foo๋ก ์ฎ๊ธด๋ค. foo์ ret ๋ช
๋ น์ด๋ ์คํ์ ๋ค์ main์ ํธ์ถ ๋ค์์ ๋์ค๋ ๋ช
๋ น์ด๋ก ์ฎ๊ธด๋ค.
์ผ๋ฐ์ ์ผ๋ก ํจ์๋ ํจ์๊ฐ ์ฌ์ฉํ ๋ณ์๋ค์ ์ ์ํ๋ค. ์ด ๋ณ์๋ค์ ์ ์งํ๋ ค๋ฉด ๊ณต๊ฐ์ด ํ์ํ๋ค. ํจ์ ํธ์ถ์ ๋ณ์๊ฐ์ ์ ์งํ๊ธฐ์ํด ์คํ์ ์ฌ์ฉํ๋ค. ํ๋ก๊ทธ๋จ ์คํ์ค์ ๋ฐ๋ณต๋๋ ์ฌ๊ทํธ์ถ์(recursive call) activation record๊ฐ ์ ์ง๋๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํ๋ค. esp๋ ebp๊ฐ์ ๋ ์ง์คํฐ ์ฌ์ฉ๋ฒ๊ณผ ์คํ์ ๋ค๋ฃจ๋ push์ pop๊ฐ์ ๋ช
๋ น์ด ์ฌ์ฉ๋ฒ์ ํจ์ํธ์ถ๊ณผ ๋ฐํ๋ฐฉ์์ ์ดํดํ๋๋ฐ ์ค์ํ๋ค.
~cpp .globl main main: movl $10, %eax call foo ret foo: addl $5, %eax ret
6. ์คํ ์ฌ์ฉํ๊ธฐ ¶
ํ๋ก๊ทธ๋จ์ ๋ฉ๋ชจ๋ฆฌ ์ผ๋ถ๋ฅผ ์คํ์ผ๋ก ์ฌ์ฉํ๊ธฐ์ํด ๋น์๋์๋ค. Intel 80386 ์ด์์ ๋ง์ดํฌ๋กํ๋ก์ธ์์๋ ์คํ ์ต์์ ์ฃผ์๋ฅผ ์ ์ฅํ๋, ์คํํฌ์ธํฐ(stack pointer)๋ผ๋ esp ๋ ์ง์คํฐ๊ฐ ์๋ค. ์๋ ๊ทธ๋ฆผ 1์ ์คํ์ ์ ์ฅ๋ ์ธ ์ ์๊ฐ 49, 30, 72๋ฅผ ๋ณด์ฌ์ค๋ค (์ ์๋ ๊ฐ๊ฐ 4 ๋ฐ์ดํธ๋ฅผ ์ฐจ์งํ๋ค). esp ๋ ์ง์คํฐ๋ ์คํ ์ต์์ ์ฃผ์๋ฅผ ์ ์ฅํ๋ค.
๊ทธ๋ฆผ 1
์๋ก ์์ฌ๊ฐ๋ ๋ฒฝ๋๊ณผ ๋ฌ๋ฆฌ Intel ์ปดํจํฐ์ ์คํ์ ์๋๋ฐฉํฅ์ผ๋ก ์๋๋ค. ๊ทธ๋ฆผ 2๋ ๋ช
๋ น์ด pushl $15๋ฅผ ์คํํํ ์คํ์ ๋ณด์ฌ์ค๋ค.
๊ทธ๋ฆผ 2
์คํํฌ์ธํฐ ๋ ์ง์คํฐ๋ 4๋งํผ ๊ฐ์ํ๊ณ , ์ซ์ 15๋ฅผ 4 ๋ฐ์ดํธ(์ฃผ์ 1988, 1989, 1990, 1991)์ ์ ์ฅํ๋ค.
๋ช
๋ น์ด popl %eax๋ ์คํ ์ต์์์ ์๋ ๊ฐ(4 ๋ฐ์ดํธ)์ eax ๋ ์ง์คํฐ์ ๋ณต์ฌํ๊ณ esp๋ฅผ 4๋งํผ ์ฆ๊ฐํ๋ค. ๋ง์ฝ ์คํ ์ต์์์ ์๋ ๊ฐ์ ๋ ์ง์คํฐ์ ๋ณต์ฌํ๊ณ ์ถ์ง ์๋ค๋ฉด? ๋ช
๋ น์ด addl $4, %esp๋ฅผ ์คํํ์ฌ ์คํํฌ์ธํฐ๋ง ์ฆ๊ฐํ๋ฉด ๋๋ค.
๋ชฉ๋ก 3์์ ๋ช
๋ น์ด call foo๋ ํธ์ถ์ ๋ง์นํ ์คํํ ๋ช
๋ น์ด์ ์ฃผ์๋ฅผ ์คํ์ ๋ฃ๊ณ foo๋ก ๋ถ๊ธฐํ๋ค. ํจ์๋ ret์์ ๋๋๊ณ , ์คํ์ ์คํ ์ต์์์์ ๊ฐ์ ธ์จ ์ฃผ์์ ์๋ ๋ช
๋ น์ด๋ก ์ฎ๊ธด๋ค. ๋ฌผ๋ก ์คํ ์ต์์์ ์ ํจํ ๋ฐํ์ฃผ์๊ฐ ์์ด์ผ ํ๋ค.
7. ์ง์ญ๋ณ์(local variable) ๊ณต๊ฐ ํ ๋นํ๊ธฐ ¶
C ํ๋ก๊ทธ๋จ์ ์๋ฐฑ ์์ฒ๊ฐ์ ๋ณ์๋ฅผ ๋ค๋ฃฐ ์ ์๋ค. C ํ๋ก๊ทธ๋จ์ ํด๋นํ๋ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ ์ด๋ป๊ฒ ๋ณ์๋ฅผ ์ ์ฅํ๋ฉฐ ๋ณ์๋ฅผ ๋ค๋ฃจ๊ธฐ์ํด ๋ ์ง์คํฐ๋ฅผ ์ถฉ๋์์ด ์ฌ์ฉํ๋์ง ์๋ ค์ค๋ค.
๋ ์ง์คํฐ ๊ฐ์๊ฐ ์ ๊ธฐ๋๋ฌธ์ ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ๋ณ์๋ฅผ ๋ ์ง์คํฐ์ ๋ด์ ์๋ ์๋ค. ์ง์ญ๋ณ์๋ ์คํ์ ์์นํ๋ค. ๋ชฉ๋ก 4๊ฐ ๊ทธ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋ค.
#๋ชฉ๋ก 4
๋จผ์ ์คํํฌ์ธํฐ์ ๊ฐ์ ๊ธฐ์คํฌ์ธํฐ ๋ ์ง์คํฐ(base pointer register) ebp์ ๋ณต์ฌํ๋ค. ๊ธฐ์คํฌ์ธํฐ๋ ์คํ์ ๋ค๋ฅธ ์์น๋ฅผ ์ ๊ทผํ ๋ ์ฌ์ฉํ ๊ณ ์ ๋ ๊ธฐ์ค์ ์ด๋ค. foo๋ฅผ ํธ์ถํ ์ฝ๋์์๋ ebp๋ฅผ ์ฌ์ฉํ๋ฏ๋ก, ๊ฐ์ esp ๊ฐ์ผ๋ก ๋์ฒดํ๊ธฐ ์ ์ ์คํ์ ๋ณต์ฌํ๋ค. ๋ช
๋ น์ด subl $4, %esp๋ ์คํํฌ์ธํฐ๋ฅผ ๊ฐ์ํ์ฌ ์ ์๋ฅผ ๋ด๊ธฐ์ํ (4 ๋ฐ์ดํธ) ๊ณต๊ฐ์ ๋ง๋ ๋ค. ๋ค์ ์ค์ ๊ฐ 10์ ebp์์ 4๋ฅผ ๋บ (4 ๋ฐ์ดํธ) ์ฃผ์์ ๋ณต์ฌํ๋ค. ๋ช
๋ น์ด movl %ebp, %esp๋ ์คํํฌ์ธํฐ๋ฅผ foo ์์์ ๊ฐ์ก๋ ๊ฐ์ผ๋ก ๋๋๋ฆฌ๊ณ , popl %ebp๋ ๊ธฐ์คํฌ์ธํฐ ๋ ์ง์คํฐ์ ๊ฐ์ ๋๋๋ฆฐ๋ค. ์คํํฌ์ธํฐ๋ ์ด์ foo๋ฅผ ์์ํ๊ธฐ ์ ๊ณผ ๊ฐ์ ๊ฐ์ ๊ฐ์ง๋ค. ์๋ ํ๋ main ์์๊ณผ ๋ชฉ๋ก 4์ (main์์ ๋ฐํ์ ์ ์ธํ) ๊ฐ ๋ช
๋ น์ด ์คํํ ๋ ์ง์คํฐ ebp, esp์ 3988์์ 3999๊น์ง ์คํ ์ฃผ์์ ๋ด์ฉ์ด๋ค. ์ฐ๋ฆฌ๋ main์ ์ฒซ ๋ช
๋ น์ด ์คํ์ ์ ebp๋ ๊ฐ 7000, esp๋ ๊ฐ 4000์ ๊ฐ์ง๋ฉฐ, ์คํ ์ฃผ์ 3988์์ 3999๊น์ง ์์์ ๊ฐ 219986, 1265789, 86์ด ์ ์ฅ๋์๋ค๊ณ ๊ฐ์ ํ๋ค. ๋, main์์ call foo ๋ค์์ ๋์ค๋ ๋ช
๋ น์ด์ ์ฃผ์๊ฐ 30000์ด๋ผ๊ณ ๊ฐ์ ํ๋ค.
ํ 1
~cpp .globl main main: call foo ret foo: pushl %ebp movl %esp, %ebp subl $4, %esp movl $10, -4(%ebp) movl %ebp, %esp popl %ebp ret
8. ํ๋ผ๋ฏธํฐ ์ ๋ฌ๊ณผ ๊ฐ ๋ฐํ ¶
ํจ์๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ๊ธฐ์ํด ์คํ์ ์ฌ์ฉํ ์ ์๋ค. ์ฐ๋ฆฌ๋ ํจ์๊ฐ eax ๋ ์ง์คํฐ์ ์ ์ฅํ ๊ฐ์ด ํจ์์ ๋ฐํ๊ฐ์ด๋ผ๋ (์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ C ์ปดํ์ผ๋ฌ์) ๊ท์น์ ๋ฐ๋ฅธ๋ค. ํจ์๋ฅผ ํธ์ถํ๋ ํ๋ก๊ทธ๋จ์ ์คํ์ ๊ฐ์ ๋ฃ์ด์ ํจ์์๊ฒ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ๋ค. ๋ชฉ๋ก 5๋ sqr์ด๋ผ๋ ๊ฐ๋จํ ํจ์๋ก ์ด๋ฅผ ์ค๋ช
ํ๋ค.
#๋ชฉ๋ก 5
sqr์ ์ฒซ๋ฒ์งธ ์ค์ ์ฃผ์์๊ฒ ์ดํด๋ผ. ํจ์๋ฅผ ๋ถ๋ฅด๋ ์ธก์ ebx์ ๋ด์ฉ์ ์คํ์ ๋ฃ๊ณ ๋ช
๋ น์ด call์ ์คํํ๋ค. ํธ์ถ์ ๋ฐํ์ฃผ์๋ฅผ ์คํ์ ๋ฃ๋๋ค. ๊ทธ๋ฆฌ๊ณ sqr๋ ์คํ ์ต์์์์ 4 ๋ฐ์ดํธ ๋จ์ด์ง ๊ณณ์์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ์ ์ ์๋ค.
~cpp .globl main main: movl $12, %ebx pushl %ebx call sqr addl $4, %esp //esp๋ฅผ push ์ด์ ๊ฐ์ผ๋ก ์กฐ์ ret sqr: movl 4(%esp), %eax imull %eax, %eax //eax * eax๋ฅผ ๊ณ์ฐํ์ฌ, ๊ฒฐ๊ณผ๋ฅผ eax์ ์ ์ฅ ret
9. C์ ์ด์ ๋ธ๋ฌ ์๊ธฐ ¶
๋ชฉ๋ก 6์ C ํ๋ก๊ทธ๋จ๊ณผ ์ด์
๋ธ๋ฆฌ์ด ํจ์๋ฅผ ๋ณด์ฌ์ค๋ค. ํ์ผ main.c์ C ํจ์๊ฐ ์๊ณ sqr.s์ ์ด์
๋ธ๋ฆฌ์ด ํจ์๊ฐ ์๋ค. cc main.c sqr.s๋ฅผ ์
๋ ฅํ์ฌ ํ์ผ๋ค์ ์ปดํ์ผํ๊ณ ๊ฐ์ด ๋งํฌํ๋ค.
๋ฐ๋๋ ๋งค์ฐ ๊ฐ๋จํ๋ค. ๋ชฉ๋ก 7์ C ํจ์ print์ ์ด ํจ์๋ฅผ ํธ์ถํ๋ ์ด์
๋ธ๋ฆฌ์ด๋ฅผ ๋ณด์ฌ์ค๋ค.
#๋ชฉ๋ก 6
~cpp //main.c main() { int i = sqr(11); printf("%d\n",i); } //sqr.s .globl sqr sqr: movl 4(%esp), %eax imull %eax, %eax ret #๋ชฉ๋ก 7 //print.c print(int i) { printf("%d\n",i); } //main.s .globl main main: movl $123, %eax pushl %eax call print addl $4, %esp ret
10. GNU C๊ฐ ๋ง๋๋ ์ด์ ๋ธ๋ฌ ์ถ๋ ฅ ¶
๋๋ ์ด ๊ธ์ด gcc๊ฐ ๋ง๋๋ ์ด์
๋ธ๋ฌ ์ถ๋ ฅ์ ์ดํดํ๊ธฐ์ ์ถฉ๋ถํ๊ธธ ๊ธฐ๋ํ๋ค. ๋ชฉ๋ก 8์ gcc -S add.c๋ก ๋ง๋ ํ์ผ add.s๋ฅผ ๋ณด์ฌ์ค๋ค. add.s๋ฅผ ํธ์งํ์ฌ ๋ง์ (๋๋ถ๋ถ ์ ๋ ฌ(alignment) ๋ฑ์ ๋ชฉ์ ์) ์ด์
๋ธ๋ฌ ์ง์์ด๋ฅผ ์ญ์ ํ์์์ ๋ฐํ๋ค.
#๋ชฉ๋ก 8
์ด ํ๋ก๊ทธ๋จ์ C ๋ฌธ์ฅ add(10,20)์ด ๋ค์๊ณผ ๊ฐ์ ์ด์
๋ธ๋ฌ์ฝ๋๋ก ๋ณํ๋จ์ ํ์ธํ๋ฉด ๋ช
ํํด์ง๋ค:
๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ฅผ ๋จผ์ ๋ฃ๋ ๊ฒ์ ์ฃผ๋ชฉํ๋ผ.
10. ์ ์ญ๋ณ์(global variable)
์ง์ญ๋ณ์์ ๊ณต๊ฐ์ ์คํ ํฌ์ธํฐ๋ฅผ ๊ฐ์ํ์ฌ ์คํ์ ํ๋ณดํ๊ณ , ๋จ์ํ ์คํํฌ์ธํฐ๋ฅผ ๋๋ ค์ ํ ๋น๋ ๊ณต๊ฐ์ ๋๋๋ฆฐ๋ค. ๊ทธ๋ฌ๋ฉด GNU C๊ฐ ์ ์ญ๋ณ์์ ๋ํด์๋ ์ด๋ค ์ฝ๋๋ฅผ ์์ฑํ ๊น? ๋ชฉ๋ก 9๊ฐ ํด๋ต์ ์ค๋ค.
#๋ชฉ๋ก 9
๋ฌธ์ฅ foo: .long 10์ foo๋ผ๋ 4 ๋ฐ์ดํธ ๋ฉ์ด๋ฆฌ๋ฅผ ์ ์ํ๊ณ , ์ด ๋ฉ์ด๋ฆฌ๋ฅผ 10์ผ๋ก ์ด๊ธฐํํ๋ค. ์ง์์ด .globl foo๋ ๋ค๋ฅธ ํ์ผ์์๋ foo๋ฅผ ์ ๊ทผํ ์ ์๋๋ก ํ๋ค. ์ด์ ์ด๊ฒ์ ์ดํด๋ณด์. ๋ฌธ์ฅ int foo๋ฅผ static int foo๋ก ์์ ํ๋ค. ์ด์
๋ธ๋ฆฌ์ฝ๋๊ฐ ์ด๋ป๊ฒ ์ดํด๋ด๋ผ. ์ด์
๋ธ๋ฌ ์ง์์ด .globl์ด ๋น ์ง ๊ฒ์ ํ์ธํ ์ ์๋ค. (double, long, short, const ๋ฑ) ๋ค๋ฅธ storage class์ ๋ํด์๋ ์๋ํด๋ณด๋ผ.
~cpp //add.c int add(int i,int j) { int p = i + j; return p; } //add.s .globl add add: pushl %ebp movl %esp, %ebp subl $4, %esp //์ ์ p์ ๊ณต๊ฐ ์์ฑ movl 8(%ebp),%edx //8(%ebp)๋ i๋ฅผ ์ง์นญ addl 12(%ebp), %edx //12(%ebp)๋ j๋ฅผ ์ง์นญ movl %edx, -4(%ebp) //-4(%ebp)๋ p๋ฅผ ์ง์นญ movl -4(%ebp), %eax //๋ฐํ๊ฐ์ eax์ ์ ์ฅ leave //์ฆ, movl %ebp, %esp; popl %ebp ret
~cpp pushl $20 pushl $10 call add
์ง์ญ๋ณ์์ ๊ณต๊ฐ์ ์คํ ํฌ์ธํฐ๋ฅผ ๊ฐ์ํ์ฌ ์คํ์ ํ๋ณดํ๊ณ , ๋จ์ํ ์คํํฌ์ธํฐ๋ฅผ ๋๋ ค์ ํ ๋น๋ ๊ณต๊ฐ์ ๋๋๋ฆฐ๋ค. ๊ทธ๋ฌ๋ฉด GNU C๊ฐ ์ ์ญ๋ณ์์ ๋ํด์๋ ์ด๋ค ์ฝ๋๋ฅผ ์์ฑํ ๊น? ๋ชฉ๋ก 9๊ฐ ํด๋ต์ ์ค๋ค.
~cpp //glob.c int foo = 10; main() { int p = foo; } //glob.s .globl foo foo: .long 10 .globl main main: pushl %ebp movl %esp,%ebp subl $4,%esp movl foo,%eax movl %eax,-4(%ebp) leave ret
11. ์์คํ ํธ์ถ(system call) ¶
ํ๋ก๊ทธ๋จ์ด ์ด์
๋ธ๋ฆฌ๋ก ์ํ ์๊ณ ๋ฆฌ์ฆ๋ง์ ๊ตฌํํ์ง ์๋๋ค๋ฉด, ์
๋ ฅ์ ๋ฐ๊ณ , ์ถ๋ ฅํ๊ณ , ์ข
๋ฃํ๋ ๋ฑ ์ด๋ค ์์
์ด ํ์ํ๋ค. ์ด๋ฅผ ์ํด ์ด์์ฒด์ ์๋น์ค๋ฅผ ํธ์ถํด์ผ ํ๋ค. ์ฌ์ค ์ด์์ฒด์ ์๋น์ค๋ฅผ ์ ์ธํ๊ณ ๋ ์ฌ๋ฌ ์ด์์ฒด์ ๊ฐ์ ์ด์
๋ธ๋ฆฌ์ด ํ๋ก๊ทธ๋๋ฐ์ด ๋งค์ฐ ๋น์ทํ๋ค.
๋ฆฌ๋
์ค์๋ ์์คํ
ํธ์ถ์ ํ๋ ๋๊ฐ์ง ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด ์๋ค: C ๋ผ์ด๋ธ๋ฌ๋ฆฌ (libc) wrapper๋ฅผ ํตํ๊ฑฐ๋, ์ง์ .
Libc wrapper๋ ์์คํ
ํธ์ถ ๊ท์น์ด ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ ํ๋ก๊ทธ๋จ์ ๋ณดํธํ๊ณ , ์ปค๋์ ๊ทธ๋ฐ ์์คํ
ํธ์ถ์ด ์๋ ๊ฒฝ์ฐ POSIX ํธํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ธฐ์ํด ๋ง๋ค์ด์ก๋ค. ๊ทธ๋ฌ๋, ์ ๋์ค ์ปค๋์ ๋ณดํต ๊ฑฐ์ POSIX์ ํธํํ๋ค: ์ฆ ๋๋ถ๋ถ์ libc "์์คํ
์ฝ"์ ๋ฌธ๋ฒ์ ์ค์ ์ปค๋ ์์คํ
ํธ์ถ์ ๋ฌธ๋ฒ๊ณผ (๋ฐ๋๋ก๋) ์ ํํ ์ผ์นํ๋ค. ๊ทธ๋ฌ๋ libc๋ฅผ ๋ฒ๋ฆฌ์ง์๋ ์ด์ ๋ ์์คํ
์ฝ wrapper์ธ์ printf(), malloc() ๋ฑ ํจ์๋ ์๊ธฐ๋๋ฌธ์ด๋ค.
๋ฆฌ๋
์ค ์์คํ
ํธ์ถ์ int 0x80์ ํตํด ํ๋ค. ๋ฆฌ๋
์ค๋ ์ผ๋ฐ์ ์ธ ์ ๋์ค ํธ์ถ ๊ท์น๊ณผ ๋ค๋ฅธ "fastcall" ๊ท์น์ ์ฌ์ฉํ๋ค. ์์คํ
ํจ์ ๋ฒํธ๋ eax์, ์๊ท๋จผํธ๋ ์คํ์ด ์๋ ๋ ์ง์คํฐ๋ฅผ ํตํด ์ ๋ฌํ๋ค. ๋ฐ๋ผ์ ebx, ecx, edx, esi, edi, ebp์ ์๊ท๋จผํธ 6๊ฐ๊น์ง ๊ฐ๋ฅํ๋ค. ์๊ท๋จผํธ๊ฐ ๋ ์๋ค๋ฉด ๊ฐ๋จํ ๊ตฌ์กฐ์ฒด๋ฅผ ์ฒซ๋ฒ์งธ ์๊ท๋จผํธ๋ก ๋๊ธด๋ค. ๊ฒฐ๊ณผ๋ eax๋ก ๋ฐํํ๊ณ , ์คํ์ ์ ํ ๊ฑด๋๋ฆฌ์ง ์๋๋ค.
์๋ ๋ชฉ๋ก 10์ ์ดํด๋ณด์.
#๋ชฉ๋ก 10
๋ช
๋ น์ด cc -g fork.c -static์ผ๋ก ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํ๋ค. gdb ๋๊ตฌ์์ ๋ช
๋ น์ด disassemble fork๋ฅผ ์
๋ ฅํ๋ค. fork์ ํด๋นํ๋ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ๋ณผ ์ ์๋ค. -static์ GCC์ ์ ์ ๋ง์ปค ์ต์
์ด๋ค (manpage ์ฐธ๊ณ ). ๋ค๋ฅธ ์์คํ
ํธ์ถ๋ ํ
์คํธํด๋ณด๊ณ ์ค์ ์ด๋ป๊ฒ ํจ์๊ฐ ๋์ํ๋์ง ์ดํด๋ด๋ผ.
๋ฆฌ๋
์ค ์์คํ
ํธ์ถ์ ๋ํ ์ต์ ๋ฌธ์๊ฐ ๋ง์์ ์ฌ๊ธฐ์ ๋ฐ๋ณตํ์ง ์๊ฒ ๋ค.
~cpp #fork.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { fork(); printf("Hello\n"); return 0; }
12. ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฆฌ ํ๋ก๊ทธ๋๋ฐ ¶
GNU C๋ x86 ์ํคํ
์ณ๋ฅผ ๋งค์ฐ ์ ์ง์ํ๋ฉฐ, C ํ๋ก๊ทธ๋จ์ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ์ฝ์
ํ ์ ์๋ค. ๋ ์ง์คํฐ ํ ๋น์ ์ง์ ์ง์ํ๊ฑฐ๋ GCC์ ๋งก๊ฒจ๋ ์ ์๋ค. ๋ฌผ๋ก , ์ด์
๋ธ๋ฆฌ ๋ช
๋ น์ด๋ ์ํคํ
์ณ๋ง๋ค ๋ค๋ฅด๋ค.
asm ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ด์
๋ธ๋ฆฌ ๋ช
๋ น์ด๋ฅผ C๋ C++ ํ๋ก๊ทธ๋จ์ ์ฝ์
ํ ์ ์๋ค. ์๋ฅผ ๋ค์ด:
๋ ๋ค์ C ๋ฌธ์ฅ์ x86 ์์ผ๋ก ์ฝ๋ฉํ ๊ฒ์ด๋ค:
์ผ๋ฐ์ ์ธ ์ด์
๋ธ๋ฆฌ์ฝ๋ ๋ช
๋ น์ด์ ๋ฌ๋ฆฌ asm ๋ฌธ์ฅ์ C ๋ฌธ๋ฒ์ผ๋ก ์
๋ ฅ๊ณผ ์ถ๋ ฅ ์ฐ์ฐ์๋ฅผ ์ง์ ํ ์ ์๋ค. Asm ๋ฌธ์ฅ์ ์๋ฌด๋๋ ์ฌ์ฉํ๋ฉด ์๋๋ค. ๊ทธ๋ฌ๋ฉด ์ธ์ ์ฌ์ฉํด์ผ ํ๋?
Asm ๋ฌธ์ฅ์ ํ๋ก๊ทธ๋จ์ด ์ปดํจํฐ ํ๋์จ์ด์ ์ง์ ์ ๊ทผํ๊ฒ ํ๋ค. ๊ทธ๋์ ๋นจ๋ฆฌ ์คํ๋๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์๋ค. ํ๋์จ์ด์ ์ง์ ์ํธ์์ฉํ๋ ์ด์์ฒด์ ์ฝ๋๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, /usr/include/asm/io.h์๋ ์
์ถ๋ ฅ ํฌํธ๋ฅผ ์ง์ ์ ๊ทผํ๊ธฐ์ํ ์ด์
๋ธ๋ฆฌ ๋ช
๋ น์ด๊ฐ ์๋ค.
๋, ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฆฌ ๋ช ๋ น์ด๋ ํ๋ก๊ทธ๋จ์ ๊ฐ์ฅ ์์ชฝ ๋ฐ๋ณต๋ฌธ์ ์๋๋ฅผ ๋น ๋ฅด๊ฒํ๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฐ์ ๊ฐ๋์ ๋ํ sine๊ณผ cosine์ fsincos x86 ๋ช ๋ น์ด๋ก ์ป์ ์ ์๋ค. ์๋ง๋ ์๋ ๋ ๋ชฉ๋ก์ ์ด ์ ์ ์ ์ดํดํ๋๋ก ๋์์ค ๊ฒ์ด๋ค.
#๋ชฉ๋ก 11
#์ด๋ฆ : bit-pos-loop.c
#์ค๋ช : ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ์ฌ ๋นํธ ์์น ์ฐพ๊ธฐ
#๋ชฉ๋ก 12
#์ด๋ฆ : bit-pos-asm.c
#์ค๋ช : bsrl์ ์ฌ์ฉํ์ฌ ๋นํธ ์์น ์ฐพ๊ธฐ
๋ค์๊ณผ ๊ฐ์ด ์ต์์ ์ต์ ํ๋ก ๋ ์ฝ๋๋ฅผ ์ปดํ์ผํ๋ค:
์ต์ํ ๋ช ์ด๋์ ์คํ๋๋๋ก ํฐ ๊ฐ์ ๋ช
๋ นํ ์๊ท๋จผํธ๋ก ์ฃผ๊ณ time ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์ฝ๋์ ์คํ์๊ฐ์ ์ฐ๋ค.
and
๊ฒฐ๊ณผ๋ ์ปดํจํฐ๋ง๋ค ๋ค๋ฅผ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ ์ธ๋ผ์ธ ์ด์
๋ธ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ฝ๋๊ฐ ๋งค์ฐ ๋น ๋ฅด๊ฒ ์คํ๋จ์ ํ์ธํ ์ ์๋ค.
GCC์ ์ต์ ํ๋ asm ํํ์ด ์๋๋ผ๋ ์คํ์๊ฐ์ ์ต์ํํ๊ธฐ์ํด ํ๋ก๊ทธ๋จ ์ฝ๋๋ฅผ ์ฌ๋ฐฐ์ดํ๊ณ ์ฌ์์ฑํ๋ ค๊ณ ์๋ํ๋ค. asm์ ์ถ๋ ฅ๊ฐ์ ์ฌ์ฉํ์ง ์๋๋ค๊ณ ํ๋จํ๋ฉด, asm๊ณผ ์๊ท๋จผํธ ์ฌ์ด์ ํค์๋ volatile์ด ์๋ ํ ์ต์ ํ๋ ๋ช
๋ น์ด๋ฅผ ์๋ตํ๋ค. (ํน๋ณํ ๊ฒฝ์ฐ๋ก GCC๋ ์ถ๋ ฅ ์ฐ์ฐ์๊ฐ ์๋ asm์ ๋ฐ๋ณต๋ฌธ ๋ฐ์ผ๋ก ์ฎ๊ธฐ์ง ์๋๋ค.) asm์ ์์ธกํ๊ธฐ ํ๋ ๋ฐฉ์์ผ๋ก, ์ฌ์ง์ด ํธ์ถ๊ฐ์๋, ์ฎ๊ฒจ์ง ์ ์๋ค. ํน๋ณํ ์ด์
๋ธ๋ฆฌ ๋ช
๋ น์ด ์์๋ฅผ ๋ณด์ฅํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ ๋ชจ๋ ๋ช
๋ น์ด๋ฅผ ๋ชจ๋ ๊ฐ์ asm์ ํฌํจํ๋ ๊ฒ์ด๋ค.
์ปดํ์ผ๋ฌ๊ฐ asm์ ์๋ฏธ๋ฅผ ๋ชจ๋ฅด๊ธฐ๋๋ฌธ์ asm์ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ๋ฌ์ ํจ์จ์ฑ์ ์ ํํ ์ ์๋ค. GCC๋ ์ด๋ค ์ต์ ํ๋ฅผ ๋ง์ ์ ์๋ ๋ณด์์ ์ธ ์ถ์ธก์ ํ๊ฒ ๋๋ค.
~cpp asm ("fsin" : "=t" (answer) : "0" (angle));
~cpp answer = sin(angle);
๋, ์ธ๋ผ์ธ ์ด์ ๋ธ๋ฆฌ ๋ช ๋ น์ด๋ ํ๋ก๊ทธ๋จ์ ๊ฐ์ฅ ์์ชฝ ๋ฐ๋ณต๋ฌธ์ ์๋๋ฅผ ๋น ๋ฅด๊ฒํ๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฐ์ ๊ฐ๋์ ๋ํ sine๊ณผ cosine์ fsincos x86 ๋ช ๋ น์ด๋ก ์ป์ ์ ์๋ค. ์๋ง๋ ์๋ ๋ ๋ชฉ๋ก์ ์ด ์ ์ ์ ์ดํดํ๋๋ก ๋์์ค ๊ฒ์ด๋ค.
#๋ชฉ๋ก 11
#์ด๋ฆ : bit-pos-loop.c
#์ค๋ช : ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ์ฌ ๋นํธ ์์น ์ฐพ๊ธฐ
~cpp #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { long max = atoi (argv[1]); long number; long i; unsigned position; volatile unsigned result; for (number = 1; number <= max; ; ++number) { for (i=(number>>1), position=0; i!=0; ++position) i >>= 1; result = position; } return 0; }
#์ด๋ฆ : bit-pos-asm.c
#์ค๋ช : bsrl์ ์ฌ์ฉํ์ฌ ๋นํธ ์์น ์ฐพ๊ธฐ
~cpp #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { long max = atoi(argv[1]); long number; unsigned position; volatile unsigned result; for (number = 1; number <= max; ; ++number) { asm("bsrl %1, %0" : "=r" (position) : "r" (number)); result = position; } return 0; }
~cpp $ cc -O2 -o bit-pos-loop bit-pos-loop.c $ cc -O2 -o bit-pos-asm bit-pos-asm.c
~cpp $ time ./bit-pos-loop 250000000
~cpp $ time ./bit-pos-asm 250000000
13. ์ฐ์ต๋ฌธ์ ¶
๋ชฉ๋ก 6์ C ํ๋ก๊ทธ๋จ์ ๋ํ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ํด์ํ๋ผ. ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ์์ฑํ ๋ -Wall ์ต์
์ด ์ถ๋ ฅํ๋ ์ค๋ฅ๊ฐ ์๋๋ก ์์ ํ๋ผ. ๋ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ๋น๊ตํ๋ผ. ์ด๋ค ์ฐจ์ด๊ฐ ์๋๊ฐ?
์ฌ๋ฌ ์์ C ํ๋ก๊ทธ๋จ์ (-O2 ๊ฐ์) ์ต์ ํ ์ต์ ์ ์ฃผ๊ณ ๋ ์์ฃผ๊ณ ์ปดํ์ผํด๋ณด๋ผ. ๊ฒฐ๊ณผ ์ด์ ๋ธ๋ฆฌ์ฝ๋๋ฅผ ์ฝ๊ณ ์ปดํ์ผ๋ฌ๊ฐ ์ฌ์ฉํ ๊ณตํต๋ ์ต์ ํ ๊ธฐ๋ฒ์ ์ฐพ์๋ผ.
switch ๋ฌธ์ฅ์ ๋ํ ์ด์ ๋ธ๋ฆฌ์ฝ๋๋ฅผ ํด์ํ๋ผ.
์ธ๋ผ์ธ asm ๋ฌธ์ฅ์ด ์๋ ์ฌ๋ฌ ์์ C ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํด๋ณด๋ผ. ์ด๋ฐ ํ๋ก๊ทธ๋จ์ ์ด์ ๋ธ๋ฆฌ์ฝ๋์๋ ๋ฌด์จ ์ฐจ์ด๊ฐ ์๋๊ฐ?
๊ฐ์ธ์ธ ํจ์(nested function)๋ ๋ค๋ฅธ ํจ์ ("๊ฐ์ธ๋ ํจ์(enclosing function") ์์์ ์ ์๋๋ฉฐ, ๋ค์๊ณผ ๊ฐ๋ค:
๊ฐ์ธ์ธ ํจ์๋ ๊ฐ์ธ๋ ํจ์์ ๋ณ์์ ์ ๊ทผํ ์ ์๊ณ ,
๊ฐ์ธ์ธ ํจ์๋ ๊ฐ์ธ๋ ํจ์์ ์ง์ญ์ ์ด๋ค(local). ์ฆ, ๊ฐ์ธ๋ ํจ์๊ฐ ๊ฐ์ธ์ธ ํจ์์ ํฌ์ธํฐ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ฉด ๊ฐ์ธ๋ ํจ์ ๋ฐ์์ ๊ฐ์ธ์ธ ํจ์๋ฅผ ํธ์ถํ ์ ์๋ค.
๊ฐ์ธ์ธ ํจ์๋ ํจ์์ ๋ฒ์(visibility)๋ฅผ ์กฐ์ ํ๊ธฐ๋๋ฌธ์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์๋ ๋ชฉ๋ก 13์ ์ฐธ๊ณ ํ๋ผ:
#๋ชฉ๋ก 13
์ด ํ๋ก๊ทธ๋จ์ cc -S myprint.c๋ก ์ปดํ์ผํ๊ณ ์ด์
๋ธ๋ฆฌ์ฝ๋๋ฅผ ํด์ํ๋ผ. ๋, ๋ช
๋ น์ด cc -pedantic myprint.c๋ก ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํด๋ณด๋ผ. ๋ฌด์์ด ๋ณด์ด๋๊ฐ?
์ฌ๋ฌ ์์ C ํ๋ก๊ทธ๋จ์ (-O2 ๊ฐ์) ์ต์ ํ ์ต์ ์ ์ฃผ๊ณ ๋ ์์ฃผ๊ณ ์ปดํ์ผํด๋ณด๋ผ. ๊ฒฐ๊ณผ ์ด์ ๋ธ๋ฆฌ์ฝ๋๋ฅผ ์ฝ๊ณ ์ปดํ์ผ๋ฌ๊ฐ ์ฌ์ฉํ ๊ณตํต๋ ์ต์ ํ ๊ธฐ๋ฒ์ ์ฐพ์๋ผ.
switch ๋ฌธ์ฅ์ ๋ํ ์ด์ ๋ธ๋ฆฌ์ฝ๋๋ฅผ ํด์ํ๋ผ.
์ธ๋ผ์ธ asm ๋ฌธ์ฅ์ด ์๋ ์ฌ๋ฌ ์์ C ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํด๋ณด๋ผ. ์ด๋ฐ ํ๋ก๊ทธ๋จ์ ์ด์ ๋ธ๋ฆฌ์ฝ๋์๋ ๋ฌด์จ ์ฐจ์ด๊ฐ ์๋๊ฐ?
๊ฐ์ธ์ธ ํจ์(nested function)๋ ๋ค๋ฅธ ํจ์ ("๊ฐ์ธ๋ ํจ์(enclosing function") ์์์ ์ ์๋๋ฉฐ, ๋ค์๊ณผ ๊ฐ๋ค:
๊ฐ์ธ์ธ ํจ์๋ ๊ฐ์ธ๋ ํจ์์ ๋ณ์์ ์ ๊ทผํ ์ ์๊ณ ,
๊ฐ์ธ์ธ ํจ์๋ ๊ฐ์ธ๋ ํจ์์ ์ง์ญ์ ์ด๋ค(local). ์ฆ, ๊ฐ์ธ๋ ํจ์๊ฐ ๊ฐ์ธ์ธ ํจ์์ ํฌ์ธํฐ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ฉด ๊ฐ์ธ๋ ํจ์ ๋ฐ์์ ๊ฐ์ธ์ธ ํจ์๋ฅผ ํธ์ถํ ์ ์๋ค.
~cpp /* myprint.c */ #include <stdio.h> #include <stdlib.h> int main() { int i; void my_print(int k) { printf("%d\n",k); } scanf("%d",&i); my_print(i); return 0; }