이장의내용 8 장고급프로시저 스택프레임 재귀 (Recursion) Invoke, Addr, Proc, Proto 디렉티브 다중모듈프로그램작성 2 8.2 스택프레임 Stack Frame ( 또는 activation record) procedure 의다음사항을저장한 영역 urn address passed parameter ( 스택매개변수 ) saved register local variable 스택매개변수 ( parameters) 인수 (Argument) 와매개변수 (parameter) argument: calling program 이 procedure 에전달하는값 parameter: called procedure 가받는값 Procedure Parameter register parameter parameter argument calling program register?? parameter called procedure 3 4
스택매개변수 (2) 레지스터매개변수로사용되는 register의기존내용은호출이전에저장해야함. 스택매개변수는이같이저장할필요가없음 스택매개변수의유형 값인수 값에의한전달 Register parameters pushad mov esi,offset array mov ecx,lengthof array mov ebx,type array call DumpMem popad Stack parameters push TYPE array push LENGTHOF array push OFFSET array call DumpMem 참조인수 참조에의한전달 배열전달 5 6 Stack Parameter 구현 C언어 int AddTwo(int x, int y) [EBP+12] urn x + y; [EBP+8] [EBP+4] Assembly 언어 func AddTwo mov ebp, esp... Base Pointer ( 또는 Frame Pointer) y x urn addr old EBP parameter x : [EBP + 8] parameter y : [EBP + 12] 호출직후 ESP ESP, new EBP EBP 레지스터가현재 procedure 의 frame 의기준위치로사용됨 urn address 를저장한 의다음위치를가리킴 Stack parameter 접근 베이스- 오프셋주소지정방식을사용하여스택매개변수를접근. first parameter: [ebp + 8] second parameter [ebp + 12] 기호상수를정의하여사용할수있음 x equ [ebp + 8] y equ [ebp + 12] Stack Cleanup 호출시에 push 를사용하여스택에전달했던매개변수를없애야함. pop 명령어를사용할필요는없음 두가지방법 caller에서 cleanup C 호출규약 callee 에서 cleanup stdcall 호출규약 7 8
Example C 호출규약 RET Instruction.data sum DWORD?.code push 6 ; second argument (y) push 5 ; first argument (x) call AddTwo ; EAX = sum add esp, 8 ; cleanup pop 대신에사용 mov sum,eax ; save the sum AddTwo PROC esp ; base of frame mov eax,[ebp + 12] ; second argument (6) add eax,[ebp + 8] ; first argument (5) mov esp,ebp ; ( 여기서는없어도됨 ) ; 이전 frame 복원 AddTwo ENDP ; EAX contains the sum 9 Stack 에저장되어있는 urn address 로 jump EIP (IP) pop 형식 RET ; urn RET n ; urn & pointer 에 n 을더함.data AddTwo PROC sum DWORD?.code push 6 mov eax,[ebp + 12] push 5 add eax,[ebp + 8] call AddTwo add esp, 8 mov esp,ebp mov sum,eax pop bp 8 C 언어호출규약 가변길이 AddTwo ENDP 인수지원 stdcall 호출규약 10 인수전달 8/16-bit 인수, multi-word 인수 레지스터저장과복구 8-bit/16-bit 인수 32-bit 로확장한후에 에 push 16-bit 는 에 push 할수있을지라도성능저하를가져올수있다. 스택프레임을설정한후보존할레지스터를저장함 저장했던레지스터의복원한후에스택프레임을호출이전의것으로복원함. Multi-word 인수 Little-endian 순서로배치하려면상위부분을먼저 에 push 함 ( 참고 ) uses 연산자를사용하면 push를사용하여지정된레지스터를먼저저장한후에작성된명령어를실행한다. 11 12
Local Variables Static global variable all variables declared in the data segments lifetime: program이수행되는동안사용 (static) scope: program 전체에서사용가능 (global) (cf) C 언어의 global variable Local variables is created, used, and destroyed within a single procedure lifetime/scope: procedure 가호출되어수행되는동안 procedure 내에서사용 기억장소를다른용도로재사용할수있어서효율적임 Local Variable 의구현 Local Variable 은 을사용하여구현함 Local Variable 공간할당 C 언어 func() int a, b; a = 10; b = a; 함수호출직후 ESP urn addr old EBP a b 지역변수할당후 EBP ESP (cf) C 언어의함수내에서선언된 local variable 변수 a: [EBP 4] 변수 b: [EBP 8] 13 14 Local Variable 을사용한 Procedure C언어 Assembly언어 func() func proc ; ebp 보관 int a, b; mov ebp, esp ; ebp esp sub esp, 8 ; esp esp 8 a = 10; b = a; mov dword ptr [ebp-4], 10 ; a 10 mov eax, [ebp-4] mov [ebp-8], eax ; b a mov esp, ebp ; esp ebp ; ebp 복원 변수 a: [ebp 4] 변수 b: [ebp 8] func endp ebp 복원시에 local variable용 공간이정리됨 Local Variable 을사용한 Procedure (2) Symbol 로정의한 local variable 을사용한 assembly program x_local equ dword ptr [ebp-4] y_local equ dword ptr [ebp-8] func proc ; ebp 보관 mov ebp, esp ; ebp esp sub esp, 8 ; esp esp 8 mov x_local, 10 ; a 10 mov eax, x_local mov y_local, eax ;b a mov esp, ebp ; esp ebp ; ebp 복원 func endp 15 16
Stack Frames 구성 LEA Instruction Stack Frame 구성 Parameters (push) Return address (call) Old EBP (push, EBP 변경 ) Local variables (esp 감소시킴 ) Saved registers (push) push para2 push para1 mov ebp, esp call func sub esp, 8 push reg1 push reg2 EBP ESP parameter 2 parameter 1 urn addr old EBP local var 1 local l var 2 save reg 1 save reg 2 frame LEA reg, mem (load effective address) 동작 : reg mem 의 offset LEA instruction 과 OFFSET operator OFFSET operator는 direct operand에대한offset만사용가능 LEA instruction은 direct와 indirect operand모두사용가능 (local variable, parameter 모두 indirect operand임 ) local variable, parameter 의주소를필요로할때 LEA instruction을사용해야함 void makearray( ) char mystring[30]; for( int i = 0; i < 30; i++ ) mystring[i] = '*'; 17 18 LEA Instruction(2) makearray PROC sub esp,32 ; mystring is at EBP 30 lea esi,[ebp 30] ; load address of mystring mov ecx,30 ; loop counter L1: mov BYTE PTR [esi],'*' ; fill one position inc esi ; move to next loop L1 ; continue until ECX = 0 add esp,32 ; remove the array makearray ENDP 19 ENTER and LEAVE Instructions ENTER localbytes, nestinglevel procedure 을위한 frame 을만듬 LEAVE localbytes: local variable 이사용하는 공간의크기 (byte) nestinglevel: 일부고급언어에서사용하는 nesting level (assembler, FORTRAN, C 등에서는사용하지않음, 0) frame 을없앰, ENTER 의반대동작 MySub PROC enter 8,0 leave 4 MySub ENDP MySub PROC sub esp, 8 mov esp,ebp 4 MySub ENDP 20
Nesting Level 과 Block Structured Language LOCAL directive* LOCAL varlist PROC directive 바로다음에위치하여 local variable 들을선언 variable 은 type 과함께선언 MySub PROC LOCAL var1:byte, var2:word, var3:sdword Example: array, pointer LOCAL flagvals[20]:byte ; array of bytes procedure A: Main 의 frame 사용가능 procedure B: Main, A 의 frame 사용가능 procedure C: Main, A 의 frame 사용가능 procedure D: Main, A, C 의 frame 사용가능 LOCAL parray:ptr WORD ; pointer to an array LOCAL directive 의구현 Assembler는 local variable를 을사용하여구현함 21 22 MASM-Generated Code Local variable 의할당 BubbleSort PROC LOCAL temp:dword, SwapFlag:BYTE BubbleSort ENDP BubbleSort PROC sub esp,8 urn addr old EBP mov esp,ebp [EBP 4] a pop p ebp BubbleSort ENDP [EBP 8] b EBP ESP LOCAL 디렉티브에의한지역변수할당 8-bit 변수 : next available byte 16-bit 변수 : next even(word) boundary 32-bit 변수 : next double word boundary Stack pointer double word boundary 23 24
Example: SumOf SumOf PROC LOCAL tempsum:dword mov tempsum,eax add tempsum,ebxm eb add tempsum,ecx ; tempsum = eax + ebx + ecx mov eax,tempsum BubbleSort ENDP Reserving Stack Space Stack을사용하기위해서는 을위한공간을할당해야함 STACK directive segment의크기를지정. 4096 ; 4KB irvine32.incinc 에포함되어있음 (4KB) LOCAL directive를사용하여 local variable을선언하면 local variable을 [EBP 4] 와같은표기대신에 tempsum 과같은표기를사용할수있어서편리함 25 26 8.3 Recursion What is Recursion? procedure 가직접, 또는간접적으로자신을호출하는것 Call graph recursion 은 cycle 을형성함 A E A B Recursively Calculating a Sum CalcSum procedure: 정수의합을재귀적으로계산 Receives: ECX = count. Returns: EAX = sum CalcSum PROC cmp ecx,0 jz L2 add eax,ecx dec ecx call CalcSum L2: CalcSum ENDP ; check counter value ; quit if zero ; otherwise, add to sum ; decrement counter ; recursive call D C Stack frame: 27 28
Calculating a Factorial int factorial(int n) if(n == 0) urn 1; else urn n * factorial(n-1); call path factorial(5) factorial(4) factorial(3) factorial(2) factorial(1) factorial(0) 5*4! 4*3! 3*2! 2*1! 1*0! 1 urn path 29 Calculating a Factorial Factorial PROC p mov eax,[ebp+8] ; get n cmp eax,0 ; n < 0? ja L1 ; yes: continue mov eax,1 ; no: urn 1 jmp L2 L1: dec eax push eax ; Factorial(n-1) a call Factorial ; Instructions from this point on execute when each ; recursive call urns. ReturnFact: mov ebx,[ebp+8] ; get n mul ebx ; eax = eax * ebx L2: mov esp,ebp ; 없어도됨 ; urn EAX 4 ; clean up Factorial ENDP 30 Calculating a Factorial MODEL Directive 12! 계산할때의 각 recursive call 은 12byte 의 공간을사용 12 n ReturnMain ebp 1 ebp 0 11 n-1 ReturnFact ebp 2 ebp 1 10 n-2 ReturnFact ebp 3 ebp 2 9 n-3 ReturnFact ebp 4 ebp 3 (etc...) Memory Model code 와 data segment 의개수와크기를결정함 Real mode 의 memory model tiny small medium compact large huge 1 segment (code, data 모두포함 ), COM 프로그램 1 code segment, 1 data segment multiple code segments, 1 data segment 1 code segment, multiple data segments multiple code, data segments Protected mode 의 memory model single data segment 보다큰 data 사용가능 flat model : 32-bit offset 사용 ( 최대 4GB) single segment 에모든 data 와 code 가포함됨 31 32
.MODEL Directive.MODEL model [, modeloptions] program's memory model 과 model options 지정 modeloptions 은 language specifier 를포함 Language g Specifiers procedure naming scheme, parameter passing conventions 지정 specifier argument push order clean up argument C reverse order calling program pascal forward order called procedure stdcall reverse order called procedure irvine32.inc 에서는 stdcall 을사용 8 add sp, 8 33