E D R , A S I H C RSS

CTo Assembly

1. before

›๋ฌธ ถœฒ˜ : http://blog.naver.com/webman21/18265245
๋‚ดšฉด ๋ณผ๋งŒ•ด„œ ˜ฌ๋ฆผ.  .. ใ…ก.ใ…ก ด œ 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) ๋ฌธ๋ฒ•œผ๋กœ ž‘„•œ  „˜• ธ ๋ช…๋ น–ด๋Š” ๋‹คŒ๊ณผ ๊ฐ™๋‹ค:


~cpp
movl $10, %eax

ด ๋ช…๋ น–ด๋Š” eax ๋ ˆง€Šค„— ๊ฐ’ 10„  €žฅ•œ๋‹ค. ๋ ˆง€Šค„ฐ๋ช… •ž˜ `%'™€ ง ‘๊ฐ’(immediate value) •ž˜ '$'๋Š” •„ˆ˜ –ด…ˆ๋ธ”๋Ÿฌ ๋ฌธ๋ฒ•ด๋‹ค. ๋ชจ๋“  –ด…ˆ๋ธ”๋Ÿฌ๊ฐ€ ด๋Ÿฐ ๋ฌธ๋ฒ•„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ€ •„๋‹ˆ๋‹ค.

๋ชฉ๋ก 1€ first.s ŒŒผ—  €žฅ•œ šฐ๋ฆฌ˜ ฒซ๋ฒˆงธ –ด…ˆ๋ธ”๋ฆฌ–ด ”„๋กœ๊ทธ๋žจด๋‹ค.

#๋ชฉ๋ก 1
~cpp
.globl main
main:
  movl $20, %eax
  ret

cc first.s ๋ช…๋ น–ด๋ฅผ ‹ค–‰•˜๋ฉด ด ŒŒผ„ –ด…ˆ๋ธ”•˜๊ณ  ๋งฌ•˜—ฌ a.out„ ๋งŒ๋“ ๋‹ค. GNU ปดŒŒผ๋Ÿฌ •ž๋‹จ cc๊ฐ€ `.s' ™•žฅž๋ฅผ –ด…ˆ๋ธ”๋ฆฌ–ด ŒŒผ๋กœ ธ‹•˜—ฌ, ปดŒŒผ๋‹จ๊ณ„๋ฅผ ƒ๋žต•˜๊ณ  –ด…ˆ๋ธ”๋Ÿฌ™€ ๋งปค๋ฅผ ๋ถ€๋ฅธ๋‹ค.

”„๋กœ๊ทธ๋žจ˜ ฒซ๋ฒˆงธ „€ ฃผ„ด๋‹ค. –ด…ˆ๋ธ”๋Ÿฌ ง€‹œ–ด .globl€ ‹ฌ๋ณผ main„ ๋งปค๊ฐ€ ๋ณผ ˆ˜ žˆ๋„๋ก ๋งŒ๋“ ๋‹ค. ๊ทธ๋ž˜•ผ main„ ˜ธถœ•˜๋Š” C ‹œž‘๋ผด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ”„๋กœ๊ทธ๋žจ๊ณผ ๊ฐ™ด ๋งฌ•˜๋ฏ€๋กœ ค‘š”•˜๋‹ค. ด „ด —†๋‹ค๋ฉด ๋งปค๋Š” 'undefined reference to symbol main' (‹ฌ๋ณผ main— ๋Œ€•œ ฐธกฐ๊ฐ€  •˜๋˜ง€•ŠŒ)„ ถœ๋ ฅ•œ๋‹ค (•œ๋ฒˆ •ด๋ด๋ผ). ”„๋กœ๊ทธ๋žจ€ ๋‹จˆœžˆ ๋ ˆง€Šค„ฐ eax— ๊ฐ’ 20„  €žฅ•˜๊ณ  ˜ธถœž—๊ฒŒ ๋ฐ˜™˜•œ๋‹ค.

4. ‚ฐˆ ๊ณ„‚ฐ, ๋น„๊ต, ๋ฐ˜๋ณต

๋‹คŒ ๋ชฉ๋ก 2 ”„๋กœ๊ทธ๋žจ€ eax—  €žฅ๋œ ๊ฐ’˜ ๊ณ„Šน(factorial)„ ๊ณ„‚ฐ•œ๋‹ค. ๊ฒฐ๊ณผ๋ฅผ ebx—  €žฅ•œ๋‹ค.

#๋ชฉ๋ก 2
~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

L1๊ณผ L2๋Š” ๋ผ๋ฒจด๋‹ค.  œ–ด๋ฆ„ด L2— ๋„๋‹ฌ•˜๋ฉด, ebx๋Š” eax—  €žฅ๋œ ๊ฐ’˜ ๊ณ„Šน„  €žฅ•˜๊ฒŒ ๋œ๋‹ค.

5. •จˆ˜(subroutine)

๋ณตžก•œ ”„๋กœ๊ทธ๋žจ„ ๋งŒ๋“ค๋•Œ šฐ๋ฆฌ๋Š” •ด๊ฒฐ•  ๋ฌธ œ๋ฅผ ฒด๊ณ„ œผ๋กœ ๋‚˜๋ˆˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  •„𔕠๋•Œ๋งˆ๋‹ค ˜ธถœ•  •จˆ˜๋ฅผ ž‘„•œ๋‹ค. ๋ชฉ๋ก 3€ –ด…ˆ๋ธ”๋ฆฌ–ด ”„๋กœ๊ทธ๋žจ˜ •จˆ˜ ˜ธถœ๊ณผ ๋ฐ˜™˜„ ๋ณด—ฌค€๋‹ค.

#๋ชฉ๋ก 3
~cpp
.globl main
main:
	movl $10, %eax
	call foo
	ret
foo:
	addl $5, %eax
	ret

call ๋ช…๋ น–ด๋Š” ‹ค–‰„ •จˆ˜ foo๋กœ ˜ฎ๊ธด๋‹ค. foo˜ ret ๋ช…๋ น–ด๋Š” ‹ค–‰„ ๋‹ค‹œ main˜ ˜ธถœ ๋‹คŒ— ๋‚˜˜ค๋Š” ๋ช…๋ น–ด๋กœ ˜ฎ๊ธด๋‹ค.

ผ๋ฐ˜ œผ๋กœ •จˆ˜๋Š” •จˆ˜๊ฐ€ ‚ฌšฉ•  ๋ณ€ˆ˜๋“ค„  •˜•œ๋‹ค. ด ๋ณ€ˆ˜๋“ค„ œ ง€•˜๋ ค๋ฉด ๊ณต๊ฐ„ด •„š”•˜๋‹ค. •จˆ˜ ˜ธถœ‹œ ๋ณ€ˆ˜๊ฐ’„ œ ง€•˜๊ธฐœ„•ด Šคƒ„ ‚ฌšฉ•œ๋‹ค. ”„๋กœ๊ทธ๋žจ ‹ค–‰ค‘— ๋ฐ˜๋ณต๋˜๋Š” žฌ๊ท€˜ธถœ‹œ(recursive call) activation record๊ฐ€ œ ง€๋˜๋Š” ๋ฐฉ๋ฒ•„ ด•ด•˜๋Š” ๊ฒƒด ค‘š”•˜๋‹ค. esp๋‚˜ ebp๊ฐ™€ ๋ ˆง€Šค„‚ฌšฉ๋ฒ•๊ณผ Šคƒ„ ๋‹ค๋ฃจ๋Š” push™€ pop๊ฐ™€ ๋ช…๋ น–ด ‚ฌšฉ๋ฒ•€ •จˆ˜˜ธถœ๊ณผ ๋ฐ˜™˜๋ฐฉ‹„ ด•ด•˜๋Š”๋ฐ ค‘š”•˜๋‹ค.

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
~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

๋จผ € Šคƒฌธ„˜ ๊ฐ’„ ๊ธฐค€ฌธ„ฐ ๋ ˆง€Šค„ฐ(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

8. ŒŒ๋ผ๋ฏธ„ „๋‹ฌ๊ณผ ๊ฐ’ ๋ฐ˜™˜

•จˆ˜๋กœ ŒŒ๋ผ๋ฏธ„ฐ๋ฅผ  „๋‹ฌ•˜๊ธฐœ„•ด Šคƒ„ ‚ฌšฉ•  ˆ˜ žˆ๋‹ค. šฐ๋ฆฌ๋Š” •จˆ˜๊ฐ€ eax ๋ ˆง€Šค„—  €žฅ•œ ๊ฐ’ด •จˆ˜˜ ๋ฐ˜™˜๊ฐ’ด๋ผ๋Š” (šฐ๋ฆฌ๊ฐ€ ‚ฌšฉ•˜๋Š” C ปดŒŒผ๋Ÿฌ˜) ๊ทœน™„ ๋”ฐ๋ฅธ๋‹ค. •จˆ˜๋ฅผ ˜ธถœ•˜๋Š” ”„๋กœ๊ทธ๋žจ€ Šคƒ— ๊ฐ’„„–ด„œ •จˆ˜—๊ฒŒ ŒŒ๋ผ๋ฏธ„ฐ๋ฅผ  „๋‹ฌ•œ๋‹ค. ๋ชฉ๋ก 5๋Š” sqrด๋ผ๋Š” ๊ฐ„๋‹จ•œ •จˆ˜๋กœ ด๋ฅผ „ค๋ช…•œ๋‹ค.

#๋ชฉ๋ก 5
~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

sqr˜ ฒซ๋ฒˆงธ „„ ฃผ˜žˆ๊ฒŒ ‚ดŽด๋ผ. •จˆ˜๋ฅผ ๋ถ€๋ฅด๋Š” ธก€ ebx˜ ๋‚ดšฉ„ Šคƒ— ๋„ฃ๊ณ  ๋ช…๋ น–ด call„ ‹ค–‰•œ๋‹ค. ˜ธถœ‹œ ๋ฐ˜™˜ฃผ†Œ๋ฅผ Šคƒ— ๋„ฃ๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  sqr๋Š” Šคƒ ตœƒœ„—„œ 4 ๋ฐ”ดŠธ ๋–จ–ด„ ๊ณณ—„œ ŒŒ๋ผ๋ฏธ„ฐ๋ฅผ ฝ„ ˆ˜ žˆ๋‹ค.

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
~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

ด ”„๋กœ๊ทธ๋žจ€ C ๋ฌธžฅ add(10,20)ด ๋‹คŒ๊ณผ ๊ฐ™€ –ด…ˆ๋ธ”๋Ÿฌฝ”๋“œ๋กœ ๋ณ€™˜๋จ„ ™•ธ•˜๋ฉด ๋ช…™••ด„๋‹ค:


~cpp
pushl $20
pushl $10
call add

๋‘๋ฒˆงธ ŒŒ๋ผ๋ฏธ„ฐ๋ฅผ ๋จผ € ๋„ฃ๋Š” ๊ฒƒ„ ฃผ๋ชฉ•˜๋ผ.

10.  „—ญ๋ณ€ˆ˜(global variable)
ง€—ญ๋ณ€ˆ˜˜ ๊ณต๊ฐ„€ Šค…ฌธ„ฐ๋ฅผ ๊ฐ†Œ•˜—ฌ Šคƒ— ™•๋ณด•˜๊ณ , ๋‹จˆœžˆ Šคƒฌธ„ฐ๋ฅผ ๋Š˜๋ ค„œ • ๋‹น๋œ ๊ณต๊ฐ„„ ๋˜๋Œ๋ฆฐ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด GNU C๊ฐ€  „—ญ๋ณ€ˆ˜— ๋Œ€•ด„œ๋Š” –ด๋–ค ฝ”๋“œ๋ฅผ ƒ„• ๊นŒ? ๋ชฉ๋ก 9๊ฐ€ •ด๋‹ต„ ค€๋‹ค.

#๋ชฉ๋ก 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

๋ฌธžฅ foo: .long 10€ foo๋ผ๋Š” 4 ๋ฐ”ดŠธ ๋ฉ–ด๋ฆฌ๋ฅผ  •˜•˜๊ณ , ด ๋ฉ–ด๋ฆฌ๋ฅผ 10œผ๋กœ ˆ๊ธฐ™”•œ๋‹ค. ง€‹œ–ด .globl foo๋Š” ๋‹ค๋ฅธ ŒŒผ—„œ๋„ foo๋ฅผ  ‘๊ทผ•  ˆ˜ žˆ๋„๋ก •œ๋‹ค. ด œ ด๊ฒƒ„ ‚ดŽด๋ณดž. ๋ฌธžฅ int foo๋ฅผ static int foo๋กœ ˆ˜ ••œ๋‹ค. –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๊ฐ€ –ด๋–ป๊ฒŒ ‚ดŽด๋ด๋ผ. –ด…ˆ๋ธ”๋Ÿฌ ง€‹œ–ด .globlด ๋น „ ๊ฒƒ„ ™•ธ•  ˆ˜ žˆ๋‹ค. (double, long, short, const ๋“) ๋‹ค๋ฅธ storage class— ๋Œ€•ด„œ๋„ ‹œ๋„•ด๋ณด๋ผ.

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
~cpp
#fork.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
	fork();
	printf("Hello\n");
	return 0;
}

๋ช…๋ น–ด cc -g fork.c -staticœผ๋กœ ”„๋กœ๊ทธ๋žจ„ ปดŒŒผ•œ๋‹ค. gdb ๋„๊ตฌ—„œ ๋ช…๋ น–ด disassemble fork๋ฅผ ž…๋ ฅ•œ๋‹ค. fork— •ด๋‹น•˜๋Š” –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ ๋ณผ ˆ˜ žˆ๋‹ค. -static€ GCC˜  •  ๋งปค ˜ต…˜ด๋‹ค (manpage ฐธ๊ณ ). ๋‹ค๋ฅธ ‹œŠค…œ˜ธถœ๋„ …ŒŠคŠธ•ด๋ณด๊ณ  ‹ค œ –ด๋–ป๊ฒŒ •จˆ˜๊ฐ€ ๋™ž‘•˜๋Š”ง€ ‚ดŽด๋ด๋ผ.

๋ฆฌ๋ˆ…Šค ‹œŠค…œ˜ธถœ— ๋Œ€•œ ตœ‹  ๋ฌธ„œ๊ฐ€ ๋งŽ•„„œ —ฌ๊ธฐ— ๋ฐ˜๋ณต•˜ง€ •Š๊ฒ ๋‹ค.

12. ธ๋ผธ –ด…ˆ๋ธ”๋ฆฌ ”„๋กœ๊ทธ๋ž˜๋ฐ

GNU C๋Š” x86 •„‚ค…ณ๋ฅผ ๋งคšฐ ž˜ ง€›•˜๋ฉฐ, C ”„๋กœ๊ทธ๋žจ— –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ ‚ฝž…•  ˆ˜ žˆ๋‹ค. ๋ ˆง€Šค„• ๋‹น€ ง ‘ ง€‹œ•˜๊ฐ๋‚˜ GCC— ๋งก๊ฒจ๋‘˜ ˆ˜ žˆ๋‹ค. ๋ฌผ๋ก , –ด…ˆ๋ธ”๋ฆฌ ๋ช…๋ น–ด๋Š” •„‚ค…ณ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค.

asm ๋ช…๋ น–ด๋ฅผ ‚ฌšฉ•˜—ฌ –ด…ˆ๋ธ”๋ฆฌ ๋ช…๋ น–ด๋ฅผ C๋‚˜ C++ ”„๋กœ๊ทธ๋žจ— ‚ฝž…•  ˆ˜ žˆ๋‹ค. ˜ˆ๋ฅผ ๋“ค–ด:


~cpp
asm ("fsin" : "=t" (answer) : "0" (angle));

๋Š” ๋‹คŒ C ๋ฌธžฅ„ x86 ‹œผ๋กœ ฝ”๋”ฉ•œ ๊ฒƒด๋‹ค:


~cpp
answer = sin(angle);

ผ๋ฐ˜ ธ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ ๋ช…๋ น–ด™€ ๋‹ฌ๋ฆฌ asm ๋ฌธžฅ€ C ๋ฌธ๋ฒ•œผ๋กœ ž…๋ ฅ๊ณผ ถœ๋ ฅ —ฐ‚ฐˆ˜๋ฅผ ง€ ••  ˆ˜ žˆ๋‹ค. Asm ๋ฌธžฅ€ •„๋ฌด๋•Œ๋‚˜ ‚ฌšฉ•˜๋ฉด •ˆ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด –ธ œ ‚ฌšฉ•ด•ผ •˜๋‚˜?

Asm ๋ฌธžฅ€ ”„๋กœ๊ทธ๋žจด ปด“จ„•˜๋“œ›–ด— ง ‘  ‘๊ทผ•˜๊ฒŒ •œ๋‹ค. ๊ทธ๋ž˜„œ ๋นจ๋ฆฌ ‹ค–‰๋˜๋Š” ”„๋กœ๊ทธ๋žจ„ ๋งŒ๋“ค ˆ˜ žˆ๋‹ค. •˜๋“œ›–ด™€ ง ‘ ƒ˜ธž‘šฉ•˜๋Š” šด˜ฒด œ ฝ”๋“œ๋ฅผ ž‘„• ๋•Œ ‚ฌšฉ•  ˆ˜ žˆ๋‹ค. ˜ˆ๋ฅผ ๋“ค–ด, /usr/include/asm/io.h—๋Š” ž…ถœ๋ ฅ ฌŠธ๋ฅผ ง ‘  ‘๊ทผ•˜๊ธฐœ„•œ –ด…ˆ๋ธ”๋ฆฌ ๋ช…๋ น–ด๊ฐ€ žˆ๋‹ค.
๋˜, ธ๋ผธ –ด…ˆ๋ธ”๋ฆฌ ๋ช…๋ น–ด๋Š” ”„๋กœ๊ทธ๋žจ˜ ๊ฐ€žฅ •ˆชฝ ๋ฐ˜๋ณต๋ฌธ˜ †๋„๋ฅผ ๋น ๋ฅด๊ฒŒ•œ๋‹ค. ˜ˆ๋ฅผ ๋“ค–ด, –ด๋–ค ๊ฐ™€ ๊ฐ๋„— ๋Œ€•œ 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;
}

#๋ชฉ๋ก 12
#ด๋ฆ„ : 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

ตœ†Œ•œ ๋ช‡ ˆ๋™•ˆ ‹ค–‰๋˜๋„๋ก ฐ ๊ฐ’„ ๋ช…๋ น–‰ •„๊ทœ๋จผŠธ๋กœ ฃผ๊ณ  time ๋ช…๋ น–ด๋ฅผ ‚ฌšฉ•˜—ฌ ๋‘ ฝ”๋“œ˜ ‹ค–‰‹œ๊ฐ„„ žฐ๋‹ค.


~cpp
$ time ./bit-pos-loop 250000000

and


~cpp
$ time ./bit-pos-asm 250000000

๊ฒฐ๊ณผ๋Š” ปด“จ„ฐ๋งˆ๋‹ค ๋‹ค๋ฅผ ๊ฒƒด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ธ๋ผธ –ด…ˆ๋ธ”๋ฆฌ๋ฅผ ‚ฌšฉ•œ ฝ”๋“œ๊ฐ€ ๋งคšฐ ๋น ๋ฅด๊ฒŒ ‹ค–‰๋จ„ ™•ธ•  ˆ˜ žˆ๋‹ค.

GCC˜ ตœ ™”๋Š” asm ‘œ˜„ด žˆ๋”๋ผ๋„ ‹ค–‰‹œ๊ฐ„„ ตœ†Œ™”•˜๊ธฐœ„•ด ”„๋กœ๊ทธ๋žจ ฝ”๋“œ๋ฅผ žฌ๋ฐฐ—ด•˜๊ณ  žฌž‘„•˜๋ ค๊ณ  ‹œ๋„•œ๋‹ค. asm˜ ถœ๋ ฅ๊ฐ’„ ‚ฌšฉ•˜ง€ •Š๋Š”๋‹ค๊ณ  Œ๋‹จ•˜๋ฉด, asm๊ณผ •„๊ทœ๋จผŠธ ‚ฌด— ‚ค›Œ๋“œ volatileด —†๋Š” •œ ตœ ™”๋Š” ๋ช…๋ น–ด๋ฅผ ƒ๋žต•œ๋‹ค. (Šน๋ณ„•œ ๊ฒฝšฐ๋กœ GCC๋Š” ถœ๋ ฅ —ฐ‚ฐˆ˜๊ฐ€ —†๋Š” asm„ ๋ฐ˜๋ณต๋ฌธ ๋ฐ–œผ๋กœ ˜ฎ๊ธฐง€ •Š๋Š”๋‹ค.) asm€ ˜ˆธก•˜๊ธฐ ž˜๋“  ๋ฐฉ‹œผ๋กœ, ‹ฌง€–ด ˜ธถœ๊ฐ„—๋„, ˜ฎ๊ฒจˆ ˆ˜ žˆ๋‹ค. Šน๋ณ„•œ –ด…ˆ๋ธ”๋ฆฌ ๋ช…๋ น–ด ˆœ„œ๋ฅผ ๋ณดžฅ•˜๋Š” œ ผ•œ ๋ฐฉ๋ฒ•€ ๋ชจ๋“  ๋ช…๋ น–ด๋ฅผ ๋ชจ๋‘ ๊ฐ™€ asm— ฌ•จ•˜๋Š” ๊ฒƒด๋‹ค.

ปดŒŒผ๋Ÿฌ๊ฐ€ asm˜ ˜๋ฏธ๋ฅผ ๋ชจ๋ฅด๊ธฐ๋•Œ๋ฌธ— asm„ ‚ฌšฉ•˜๋ฉด ปดŒŒผ๋Ÿฌ˜ šจœจ„„  œ•œ•  ˆ˜ žˆ๋‹ค. GCC๋Š” –ด๋–ค ตœ ™”๋ฅผ ๋ง‰„ ˆ˜ žˆ๋Š” ๋ณดˆ˜ ธ ถ”ธก„ •˜๊ฒŒ ๋œ๋‹ค.

13. —ฐŠต๋ฌธ œ

๋ชฉ๋ก 6˜ C ”„๋กœ๊ทธ๋žจ— ๋Œ€•œ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ •ด„•˜๋ผ. –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ ƒ„• ๋•Œ -Wall ˜ต…˜ด ถœ๋ ฅ•˜๋Š” ˜ค๋ฅ˜๊ฐ€ —†๋„๋ก ˆ˜ ••˜๋ผ. ๋‘ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ ๋น„๊ต•˜๋ผ. –ด๋–ค ฐจด๊ฐ€ žˆ๋Š”๊ฐ€?
—ฌ๋Ÿฌ ž‘€ C ”„๋กœ๊ทธ๋žจ„ (-O2 ๊ฐ™€) ตœ ™” ˜ต…˜„ ฃผ๊ณ  ๋˜ •ˆฃผ๊ณ  ปดŒŒผ•ด๋ณด๋ผ. ๊ฒฐ๊ณผ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ ฝ๊ณ  ปดŒŒผ๋Ÿฌ๊ฐ€ ‚ฌšฉ•œ ๊ณต†ต๋œ ตœ ™” ๊ธฐ๋ฒ•„ ฐพ•„๋ผ.
switch ๋ฌธžฅ— ๋Œ€•œ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ •ด„•˜๋ผ.
ธ๋ผธ asm ๋ฌธžฅด žˆ๋Š” —ฌ๋Ÿฌ ž‘€ C ”„๋กœ๊ทธ๋žจ„ ปดŒŒผ•ด๋ณด๋ผ. ด๋Ÿฐ ”„๋กœ๊ทธ๋žจ˜ –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ—๋Š” ๋ฌดŠจ ฐจด๊ฐ€ žˆ๋Š”๊ฐ€?
๊ฐ‹ธธ •จˆ˜(nested function)๋Š” ๋‹ค๋ฅธ •จˆ˜ ("๊ฐ‹ธ๋Š” •จˆ˜(enclosing function") •ˆ—„œ  •˜๋˜๋ฉฐ, ๋‹คŒ๊ณผ ๊ฐ™๋‹ค:
๊ฐ‹ธธ •จˆ˜๋Š” ๊ฐ‹ธ๋Š” •จˆ˜˜ ๋ณ€ˆ˜—  ‘๊ทผ•  ˆ˜ žˆ๊ณ ,
๊ฐ‹ธธ •จˆ˜๋Š” ๊ฐ‹ธ๋Š” •จˆ˜— ง€—ญ ด๋‹ค(local). ฆ‰, ๊ฐ‹ธ๋Š” •จˆ˜๊ฐ€ ๊ฐ‹ธธ •จˆ˜˜ ฌธ„ฐ๋ฅผ  œ๊ณต•˜ง€ •Š๋Š”๋‹ค๋ฉด ๊ฐ‹ธ๋Š” •จˆ˜ ๋ฐ–—„œ ๊ฐ‹ธธ •จˆ˜๋ฅผ ˜ธถœ•  ˆ˜ —†๋‹ค.

๊ฐ‹ธธ •จˆ˜๋Š” •จˆ˜˜ ๋ฒ”œ„(visibility)๋ฅผ กฐ ˆ•˜๊ธฐ๋•Œ๋ฌธ— œ šฉ•˜๊ฒŒ ‚ฌšฉ•  ˆ˜ žˆ๋‹ค.

•„๋ž˜ ๋ชฉ๋ก 13„ ฐธ๊ณ •˜๋ผ:

#๋ชฉ๋ก 13
~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;
}

ด ”„๋กœ๊ทธ๋žจ„ cc -S myprint.c๋กœ ปดŒŒผ•˜๊ณ  –ด…ˆ๋ธ”๋ฆฌฝ”๋“œ๋ฅผ •ด„•˜๋ผ. ๋˜, ๋ช…๋ น–ด cc -pedantic myprint.c๋กœ ”„๋กœ๊ทธ๋žจ„ ปดŒŒผ•ด๋ณด๋ผ. ๋ฌด—‡ด ๋ณดด๋Š”๊ฐ€?
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:44
Processing time 0.0491 sec