Lazos o ciclos Procedimientos y pilas Ensamblador x86: lazos y procedimientos Lección 5 Ing. Jorge Castro-Godı́nez MT7003 Microprocesadores y Microcontroladores Área de Ingenierı́a Mecatrónica Instituto Tecnológico de Costa Rica I Semestre 2014 Jorge Castro-Godı́nez Ensamblador x86 1 / 52 Lazos o ciclos Procedimientos y pilas Contenido 1 Lazos o ciclos 2 Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Jorge Castro-Godı́nez Ensamblador x86 2 / 52 Lazos o ciclos Procedimientos y pilas Transformación de lazos o ciclos ¿Cómo transformar lazos de una forma directa? Estar seguro de dónde debe estar (u ocurrir) el salto condicional: al tope o al fondo del lazo. ¿Cómo serı́a implementar for(i=0;i<100;i++? F.8/#"%*8+:%G* 1HI.$.*8+:%G* while ( sum != 0 ) { <loop body> } loopTop: cmpl $0, %eax je loopDone <loop body code> jmp loopTop loopDone: Jorge Castro-Godı́nez Ensamblador x86 3 / 52 Lazos o ciclos Procedimientos y pilas Lazo do-while Se emplea un salto hacia atrás para continuar con el lazo. Solo toma un salto cuando la condición del while se conserva. 1*1+:%* *int fact_do(int x) { M+(+*N%&'#+"* *int fact_goto(int x) { int result = 1; do { result *= x; x = x-1; } while (x > 1); return result; } Jorge Castro-Godı́nez int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; } Ensamblador x86 4 / 52 Lazos o ciclos Procedimientos y pilas Compilación de lazo do-while M+(+*N%&'#+"* int fact_goto(int x) { int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; } %edx %eax X''%2;4)* *fact_goto: pushl %ebp movl %esp,%ebp movl $1,%eax movl 8(%ebp),%edx .L11: imull %edx,%eax decl %edx cmpl $1,%edx jg .L11 movl %ebp,%esp popl %ebp ret Jorge Castro-Godı́nez Ensamblador x86 x result # # # # Setup Setup eax = 1 edx = x # # # # result *= x x-Compare x : 1 if > goto loop # Finish # Finish # Finish 5 / 52 Lazos o ciclos Procedimientos y pilas Traducción del lazo do-while M+(+*N%&'#+"* 1*1+:%* do !"#$% while (&'()); Jorge Castro-Godı́nez loop: !"#$% if (&'()) goto loop Ensamblador x86 6 / 52 Lazos o ciclos Procedimientos y pilas Traducción del lazo while 1*1+:%* *int fact_while(int M+(+*N%&'#+"* x) { int result = 1; while (x > 1) { result *= x; x = x-1; }; return result; } Jorge Castro-Godı́nez int fact_while_goto(int x) { int result = 1; goto middle; loop: result *= x; x = x-1; middle: if (x > 1) goto loop; return result; } Ensamblador x86 7 / 52 Lazos o ciclos Procedimientos y pilas Ejemplo del lazo while int fact_while(int x) { int result = 1; while (x > 1) { result *= x; x--; }; return result; } # x in %edx, result in %eax jmp .L34 # goto Middle .L35: # Loop: imull %edx, %eax # result *= x decl %edx # x-.L34: # Middle: cmpl $1, %edx # x:1 jg .L35 # if >, goto # Loop Jorge Castro-Godı́nez Ensamblador x86 8 / 52 Lazos o ciclos Procedimientos y pilas Ciclo for (1) O`+&R*5++3*SJ.234%G*bc9.&%Q.":QF94U34)* /* Compute x raised to nonnegative power p */ int ipwr_for(int x, unsigned int p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0x1) result *= x; x = x*x; } return result; } Jorge Castro-Godı́nez Ensamblador x86 9 / 52 Lazos o ciclos Procedimientos y pilas Ciclo for O`+&R*5++3*SJ.234%G*bc9.&%Q.":QF94U34)* (2) /* Compute x raised to nonnegative power p */ int ipwr_for(int x, unsigned int p) { int result; for (result = 1; p != 0; p = p>>1) { if (p & 0x1) result *= x; x = x*x; } return result; } ;%,+&%*#(%&.U+"* result x=3 p=10 B* Z* ]* _* e* 1 1 9 9 59049 3 9 81 6561 43046721 10=10102 5= 1012 2= 102 1= 12 02 Jorge Castro-Godı́nez Ensamblador x86 10 / 52 Lazos o ciclos Procedimientos y pilas Componentes en el ciclo for int result; for (result = 1; p != 0; p = p>>1) { if (p & 0x1) result *= x; x = x*x; } M%"%&.4*`+&2* * for (1.2); &'(); 34#,)') !"#$% 1.2)% result = 1 &'()% p != 0 34#,)'% !"#$% p = p >> 1 { if (p & 0x1) result *= x; x = x*x; } Jorge Castro-Godı́nez Ensamblador x86 11 / 52 Lazos o ciclos Procedimientos y pilas De for a while `+&*N%&'#+"* * for (1.2); &'(); 34#,)'%) !"#$% M+(+*N%&'#+"* * 1.2); goto middle; loop: !"#$ 34#,)'%; middle: if (&'()) goto loop; done: -/#4%*N%&'#+"* * 1.2); while (&'()%) { !"#$% 34#,)'%;% } Jorge Castro-Godı́nez Ensamblador x86 12 / 52 Lazos o ciclos Procedimientos y pilas De for a while `+&*N%&'#+"* * for (1.2); &'(); 34#,)'%) !"#$% for (result = 1; p != 0; p = p>>1) { if (p & 0x1) result *= x; x = x*x; } M+(+*N%&'#+"* * 1.2); goto middle; loop: !"#$ 34#,)'%; middle: if (&'()) goto loop; done: result = 1; goto middle; loop: if (p & 0x1) result *= x; x = x*x; p = p >> 1; middle: if (p != 0) goto loop; done: JKL* Jorge Castro-Godı́nez Ensamblador x86 13 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Disposición de la memoria 2N-1 Stack Dynamic Data (Heap) Static Data Literals 0 (1) local variables; procedure context variables allocated with new or malloc static variables (including global variables (C)) literals (e.g., “example”) Instructions Jorge Castro-Godı́nez Ensamblador x86 14 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Disposición de la memoria (2) writable; not executable Stack Managed “automatically” (by compiler) writable; not executable Dynamic Data (Heap) Managed by programmer writable; not executable Static Data Initialized when process starts Literals Initialized when process starts Instructions Initialized when process starts Read-only; not executable Read-only; executable Jorge Castro-Godı́nez Ensamblador x86 15 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Pila en IA32 Región de memoria manejada al estilo de una pila. Crece hacia direcciones de memoria menores (es una convención). El registros %esp contiene la dirección más baja de la pila, i.e., el elemento que se encuentra en la dirección al tope de la pila, el último elementos que se colocó en la pila. Jorge Castro-Godı́nez Ensamblador x86 16 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Pila en IA32 Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %esp Stack “Top” Jorge Castro-Godı́nez Ensamblador x86 17 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Push (1) pushl src Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %esp Stack “Top” Jorge Castro-Godı́nez Ensamblador x86 18 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Push (2) pushl src Se toma el valor de src, se decrementa %esp en cuatro, el dato se almacena en Stack: la direcciónq IA32 Call Pushue indica %esp. Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %esp Jorge Castro-Godı́nez -4 Stack “Top” Ensamblador x86 19 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Pop (1) popl dest Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %esp Stack “Top” Jorge Castro-Godı́nez Ensamblador x86 20 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Pop (2) popl dest Se carga el valor apuntado por %esp, se escribe en dest, se incrementa %esp en 4. Stack “Bottom” Increasing Addresses Stack Grows Down Stack Pointer: %esp +4 Stack “Top” Jorge Castro-Godı́nez Ensamblador x86 21 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Llamadas a procedimientos (1) Callee debe saber donde encontrar los argumentos Callee debe saber donde encontrar a dirección de retorno Caller debe saber donde encontrar el valor de retorno Caller y Callee se ejecutan en el mismo procesador y, por ende, comparten los mismos registros Caller debe salvar los valores de los registros que Callee pueda usar Callee debe salvar los valores de los registros que Caller haya usado Caller … <set up args> call <clean up args> <find return val> … Jorge Castro-Godı́nez Callee <create local vars> … <set up return val> <destroy local vars> return Ensamblador x86 22 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Llamadas a procedimientos (2) La convención que permite establecer donde colocar o encontrar valores (de registros, valores de retorno) es llamadado procedure call linkage Detalles pueden variar dependiendo del sistema. Caller … <save regs> <set up args> call <clean up args> <restore regs> <find return val> … Jorge Castro-Godı́nez Callee <save regs> <create local vars> … <set up return val> <destroy local vars> <restore regs> return Ensamblador x86 23 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Control de flujo en procedimientos Llamada al procedimiento: call label Hace un push de la dirección de retorno en la pila Salta al label Retorno del procedimiento: ret Hace un pop de la dirección de retorno que se encuentra en la pila Salta a la dirección Dirección de retorno Dirección de la instrucción que se encuentra después del call Ejemplo de instrucciones desensambladas Example from disassembly: 804854e: e8 3d 06 00 00 8048553: 50 § 0x8048553 Jorge Castro-Godı́nez call pushl 8048b90 <main> %eax Ensamblador x86 24 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Ejemplo: llamada de procedimiento 804854e: 8048553: e8 3d 06 00 00 50 call pushl call (1) 8048b90 <main> %eax 8048b90 0x110 0x10c 0x108 %esp 123 0x108 %eip 0x804854e Jorge Castro-Godı́nez Ensamblador x86 25 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Ejemplo: llamada de procedimiento 804854e: 8048553: e8 3d 06 00 00 50 call pushl call 0x110 8048b90 <main> %eax 8048b90 0x110 0x10c 0x108 (2) 0x10c 123 0x108 123 0x104 %esp 0x108 %eip 0x804854e %esp 0x108 %eip 0x804854e Jorge Castro-Godı́nez Ensamblador x86 26 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Ejemplo: llamada de procedimiento 804854e: 8048553: e8 3d 06 00 00 50 call pushl call 0x110 8048b90 <main> %eax 8048b90 0x110 0x10c 0x108 (3) 0x10c 123 0x108 123 0x104 %esp 0x108 %eip 0x804854e %esp 0x108 %eip 0x804854e 0x8048553 Jorge Castro-Godı́nez Ensamblador x86 27 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Ejemplo: llamada de procedimiento 804854e: 8048553: e8 3d 06 00 00 50 call pushl call 0x110 8048b90 <main> %eax 8048b90 0x110 0x10c 0x108 (4) 0x10c 123 0x108 123 0x104 0x8048553 %esp 0x108 %eip 0x804854e %esp 0x108 0x104 %eip 0x804854e 0x8048553 Jorge Castro-Godı́nez Ensamblador x86 28 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas Ejemplo: llamada de procedimiento 804854e: 8048553: e8 3d 06 00 00 50 call pushl call 0x110 8048b90 <main> %eax 8048b90 0x110 0x10c 0x108 (5) 0x10c 123 0x108 123 0x104 0x8048553 %esp 0x108 %eip 0x804854e %esp 0x108 0x104 %eip 0x8048553 + 0x000063d 0x8048b90 Jorge Castro-Godı́nez Ensamblador x86 29 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Ejemplo: retorno de procedimiento 8048591: c3 (1) ret ret 0x110 0x10c 0x108 123 0x104 0x8048553 %esp 0x104 %eip 0x8048591 Jorge Castro-Godı́nez Ensamblador x86 30 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Ejemplo: retorno de procedimiento 8048591: c3 (2) ret ret 0x110 0x110 0x10c 0x108 0x10c 123 0x108 0x104 0x8048553 %esp 0x104 %eip 0x8048591 Jorge Castro-Godı́nez Ensamblador x86 123 0x8048553 %esp 0x104 %eip 0x8048591 31 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Ejemplo: retorno de procedimiento 8048591: c3 (3) ret ret 0x110 0x110 0x10c 0x108 0x10c 123 0x108 0x104 0x8048553 %esp 0x104 %eip 0x8048591 Jorge Castro-Godı́nez Ensamblador x86 123 0x8048553 %esp 0x104 %eip 0x8048553 0x8048591 32 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Ejemplo: retorno de procedimiento 8048591: c3 (4) ret ret 0x110 0x110 0x10c 0x108 0x10c 123 0x108 0x104 0x8048553 %esp 0x104 %eip 0x8048591 Jorge Castro-Godı́nez Ensamblador x86 123 0x8048553 %esp 0x104 0x108 %eip 0x8048553 0x8048591 33 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Valores retornados por procedimientos Por convención, los valores retornados por procedimientos son colocado en %eax Caller debe asegurarse de salvar los valores de los registros antes de llamar un Callee que devuelva un valor Callee coloca el valor de retorno (entero, flotante, puntero) Después del retorno, el Caller encuentra el valor devuelto en el registro %eax Jorge Castro-Godı́nez Ensamblador x86 34 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Linux Stack Frame Caller Frame Arguments Frame pointer %ebp Return Addr Old %ebp Saved Registers + Local Variables Stack pointer %esp Jorge Castro-Godı́nez Argument Build Ensamblador x86 35 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Función de swap (1) swap Calling swap from call_swap int zip1 = 15213; int zip2 = 98195; void call_swap() { swap(&zip1, &zip2); } call_swap: • • • pushl $zip2 pushl $zip1 call swap • • • • • • void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } Jorge Castro-Godı́nez # Global Var # Global Var Resulting Stack &zip2 &zip1 Rtn adr Ensamblador x86 %esp 36 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Función de swap (2) void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } swap: pushl %ebp movl %esp,%ebp pushl %ebx movl movl movl movl movl movl 12(%ebp),%ecx 8(%ebp),%edx (%ecx),%eax (%edx),%ebx %eax,(%edx) %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Jorge Castro-Godı́nez Ensamblador x86 Set Up Body Finish 37 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap setup (1) Entering Stack Resulting Stack %ebp %ebp • • • • • • &zip2 yp &zip1 Rtn adr xp %esp Rtn adr Old %ebp %esp swap: pushl %ebp movl %esp,%ebp pushl %ebx Jorge Castro-Godı́nez Ensamblador x86 38 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap setup (2) Entering Stack Resulting Stack %ebp • • • • • • &zip2 yp &zip1 Rtn adr xp %esp Rtn adr Old %ebp %ebp %esp swap: pushl %ebp movl %esp,%ebp pushl %ebx Jorge Castro-Godı́nez Ensamblador x86 39 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap setup (3) Entering Stack Resulting Stack %ebp • • • • • • &zip2 yp &zip1 xp Rtn adr %esp Rtn adr Old %ebp %ebp Old %ebx %esp swap: pushl %ebp movl %esp,%ebp pushl %ebx Jorge Castro-Godı́nez Ensamblador x86 40 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas swap body Entering Stack Resulting Stack %ebp • • • Offset relative to new %ebp 12 8 4 &zip2 &zip1 Rtn adr • • • %esp movl 12(%ebp),%ecx movl 8(%ebp),%edx . . . yp xp Rtn adr Old %ebp %ebp Old %ebx %esp # get yp # get xp Jorge Castro-Godı́nez Ensamblador x86 41 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap finish (1) swap’s Stack Resulting Stack • • • • • • yp yp xp xp Rtn adr Rtn adr Old %ebp %ebp Old %ebp %ebp Old %ebx %esp Old %ebx %esp movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Jorge Castro-Godı́nez Ensamblador x86 42 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap finish (2) swap’s Stack Resulting Stack • • • • • • yp yp xp xp Rtn adr Rtn adr Old %ebp %ebp Old %ebx %esp Old %ebp %ebp %esp movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Linux Stack Frame Jorge Castro-Godı́nez Ensamblador x86 43 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap finish (3) swap’s Stack Resulting Stack • • • • • • yp yp xp xp %ebp Rtn adr Rtn adr Old %ebp %ebp Old %ebx %esp %esp movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Jorge Castro-Godı́nez Ensamblador x86 44 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros swap finish (4) swap’s Stack Resulting Stack • • • • • • yp yp xp xp %ebp %esp Rtn adr Old %ebp %ebp Old %ebx %esp movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret Jorge Castro-Godı́nez Ensamblador x86 45 / 52 Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Lazos o ciclos Procedimientos y pilas swap desensamblado 080483a4 <swap>: 80483a4: 55 80483a5: 89 e5 80483a7: 53 80483a8: 8b 55 08 80483ab: 8b 4d 0c 80483ae: 8b 1a 80483b0: 8b 01 80483b2: 89 02 80483b4: 89 19 80483b6: 5b 80483b7: c9 80483b8: c3 push mov push mov mov mov mov mov mov pop leave ret %ebp %esp,%ebp %ebx 0x8(%ebp),%edx 0xc(%ebp),%ecx (%edx),%ebx (%ecx),%eax %eax,(%edx) %ebx,(%ecx) %ebx mov pop %ebp,%esp %ebp Calling Code 8048409: 804840e: e8 96 ff ff ff 8b 45 f8 Jorge Castro-Godı́nez call 80483a4 <swap> mov 0xfffffff8(%ebp),%eax Ensamblador x86 46 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Convenciones para salvar registros Cuando yoo invoca a who: yoo es el caller who es el callee En este caso %edx seı́a sobreescrito por who Can a register be used for temporary storage? yoo: • • • movl $12345, %edx call who addl %edx, %eax • • • ret %edx Jorge Castro-Godı́nez who: • • • movl 8(%ebp), %edx addl $98195, %edx • • • ret who Ensamblador x86 47 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Convenciones para salvar registros Convenciones Caller salva los valores temporales en su frame antes de llamar a otro procedimiento Callee salva los valores temporales en su frame antes de utilizar los registros. Jorge Castro-Godı́nez Ensamblador x86 48 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Uso de registros en Linux %eax, %edx, %ecx: son salvador por el caller antes de llamar a un procedimiento, si es que dichos valores se desean usar posteriormente. %eax: utilizado por defecto para almacenar los valores de retorno de las funciones. %ebx, %esi, %edi: el callee debe guardar los valores si desea usarlos. %esp, %ebp: presentan una forma especial de guardarse, lo realiza el callee. Debe restaurar los valores originales que recibe antes de salir. Jorge Castro-Godı́nez Ensamblador x86 49 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Uso de registros en Linux %eax Caller-Save Temporaries Callee-Save Temporaries Special Jorge Castro-Godı́nez %edx %ecx %ebx %esi %edi %esp %ebp Ensamblador x86 50 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Punteros a valores locales Recursive Procedure void s_helper (int x, int *accum) { if (x <= 1) return; else { int z = *accum * x; *accum = z; s_helper (x-1,accum); } } Jorge Castro-Godı́nez Top-Level Call int sfact(int x) { int val = 1; s_helper(x, &val); return val; } Ensamblador x86 51 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Crear e inicializar un puntero int sfact(int x) { int val = 1; s_helper(x, &val); return val; } Initial part of sfact _sfact: pushl %ebp movl %esp,%ebp subl $16,%esp movl 8(%ebp),%edx movl $1,-4(%ebp) 8 x 4 Rtn adr 0 Old %ebp # # # # # Save %ebp Set %ebp Add 16 bytes edx = x val = 1 Jorge Castro-Godı́nez -4 val = 1 -8 -12 -16 Ensamblador x86 %esp %ebp %esp Temp. Space Unused %esp 52 / 52 Lazos o ciclos Procedimientos y pilas Manejo de la pila Procedimientos Paso de argumentos a la pila Salvar registros Pasar un puntero int sfact(int x) { int val = 1; s_helper(x, &val); return val; } Stack at time of call: 8 4 x Rtn adr 0 Old %ebp -4 val val=x! = 1 Calling s_helper from sfact leal -4(%ebp),%eax pushl %eax pushl %edx call s_helper movl -4(%ebp),%eax • • • # # # # # # Compute &val Push on stack Push x call Return val Finish Jorge Castro-Godı́nez %ebp -8 -12 Unused -16 Ensamblador x86 %esp &val x 53 / 52