Diferencia entre revisiones de «Ejercicios varios Itanium (Organización del Computador II)»

De Cuba-Wiki
 
(Categorizado)
(No se muestran 2 ediciones intermedias del mismo usuario)
Línea 75: Línea 75:


== Fibonacci ==
== Fibonacci ==
Codigo en IA64 para calcular el késimo numero de Fibonacci. Es iterativa, no recursiva. Recibe como parámetro el k-esimo número a calcular y lo devuelve en r8.
==== Versión iterativa ====
Codigo en IA64 para calcular el késimo numero de Fibonacci. Recibe como parámetro el k-esimo número a calcular y lo devuelve en r8.


  .text
  .text
Línea 101: Línea 102:
  .endp fibo
  .endp fibo


== Versión recursiva de Fibonacci ==
==== Versión recursiva ====
Esta es la versión '''recursiva''', y que además''' no requiere ningún archivo de C''', tiene el main incororado en el código asm.
Esta versión no requiere ningún archivo de C, tiene el main incorporado en el código asm.


  .section .data
  .section .data
Línea 143: Línea 144:
  (p2) br.cond.sptk.many fin
  (p2) br.cond.sptk.many fin
 
 
   // Notar que no predico estas instrucciones, ya que como  
   // Notar que no predico estas instrucciones, ya que como  
  // los registros de predicado son fijos, quizás habría conflicto
  // los registros de predicado son fijos, quizás habría conflicto
  // dentro de las llamadas recursivas
  // dentro de las llamadas recursivas
 
  add out0=-1, in0
  add out0=-1, in0
  br.call.sptk.many b0 = fibo
  br.call.sptk.many b0 = fibo
Línea 214: Línea 214:
  br.ret.sptk.many b2;;
  br.ret.sptk.many b2;;
  .endp oper
  .endp oper
[[Category:Organización del Computador II]]
[[Category:Itanium]]
[[Category:Ejercicios]]

Revisión del 01:42 16 nov 2006

Llamadas

Suma

Ejercicio hecho en la teorica en el laboratorio sobre como llamar funciones en Itanium. Incluye el C y el assembler llamado, que a su vez llama otra funcion en assembler. El programa solamente suma dos numeros.

.text
.align 32
.global suma
.proc suma

suma:
  alloc loc0=ar.pfs, 2, 2, 2, 0;; 
  mov out0=in0
  mov out1=in1
  mov loc1=b0;;
  br.call.sptk.many b0=otro;;
  mov b0=loc1;; 
  mov ar.pfs=loc0;;
  br.ret.sptk.many b0;;

.endp suma

.proc otro
 otro:
  alloc loc0=ar.pfs, 2, 1, 0, 0;;
  add r8=in0,in1;;
  br.ret.sptk.many b0;;
.endp otro

Mientras tanto en el plano de C...

#include <stdio.h>
#include <stdlib.h>

extern int suma(int a, int b);

int main(void)
{
   int a, b;
   printf("Ingrese ");
   scanf("%i", &a);
   scanf("%i", &b);
   printf("La suma es %i", suma(a,b));
   return 0;
}

Printf

Funcion en assembler que levanta un 3 de memoria y lo pasa a un printf para mostrarlo por pantalla.

.data
dat: data8 3
str: stringz "%d"

.text
.align 32
.global printf
.global main
.proc main

main:
       alloc loc0=ar.pfs,1,3,2,0;;
       movl loc1 = dat;;
       ld8 out1 = [loc1];;

       movl out0 = str;;
       mov loc2= b0;;
       br.call.sptk.many b0 = printf;;
       mov b0 = loc2;;
       mov ar.pfs=loc0;;
       br.ret.sptk.many b0;;
.endp main

Para compilar icc -O0 ia.s -o funcion
Para ejecutar ./funcion


Fibonacci

Versión iterativa

Codigo en IA64 para calcular el késimo numero de Fibonacci. Recibe como parámetro el k-esimo número a calcular y lo devuelve en r8.

.text
.align 64
.global fibo

.proc fibo
fibo:
  alloc loc0=ar.pfs, 1, 4, 0, 0;; 
  add in0= -2, in0;;
  mov ar.LC= in0;
  mov loc1= r0;;
  mov loc2= 1;;	

ciclo1:	
  add loc3= loc1, loc2;;
  mov loc1= loc2;;
  mov loc2= loc3;;
  br.cloop.dptk.few ciclo1;; 
  // FinCiclo1

  mov ar.pfs=loc0;;
  mov r8 = loc2;
  br.ret.sptk.many b0;;
.endp fibo

Versión recursiva

Esta versión no requiere ningún archivo de C, tiene el main incorporado en el código asm.

.section .data
msg: stringz "fibonacci garca: %d\n"
.text
.align 64
.global fibo
.global printf
.global main

.proc main
main:
	alloc loc0 = ar.pfs, 0, 2, 2, 0
	mov loc1 = b0
	
	add out0 = 15, r0
	br.call.sptk.many b0 = fibo
	
	movl out0 = msg
	add out1 = ret0, r0
	br.call.sptk.many b0 = printf;;
	
	mov b0 = loc1
	mov ar.pfs = loc0
	br.ret.sptk.many b0;;
.endp main  

.proc fibo
fibo:
	alloc loc0=ar.pfs, 1, 5, 1, 0;; 
	//add in0= -2, in0;;
	mov loc1=b0
	
	mov ar.LC= in0; 

	cmp.lt p1, p2=1,in0
	(p2) cmp.eq.unc p3, p4=0,in0
	(p3) mov loc4= r0;;
	(p4) mov loc4= 1;;
	(p2) br.cond.sptk.many fin
	
 	// Notar que no predico estas instrucciones, ya que como 
	// los registros de predicado son fijos, quizás habría conflicto
	// dentro de las llamadas recursivas

	add out0=-1, in0
	br.call.sptk.many b0 = fibo
	mov loc2=ret0
	
	add out0=-2, in0
	br.call.sptk.many b0 = fibo
	mov loc3=ret0
	
	add loc4= loc2, loc3;;
	
fin:
	mov r8 = loc4;	
	mov ar.pfs=loc0;;
	mov b0=loc1
	br.ret.sptk.many b0;;
.endp fibo

Collatz

Verifica la conjetura de collatz para todos los numeros de 2 a n. El parametro es n. No calcula de a varios al mismo tiempo.

.text
.align 64
.global coll

.proc coll
coll:
  alloc loc0=ar.pfs, 1, 3, 1, 0;; 
  mov loc2= 2;;

ciclo1:	
  mov loc1= loc2;; // Meto el i en r

  ciclo2: 
     br.call.sptk.few b2=oper;; 
     mov loc1= r8;;
     cmp.ge p2, p1= loc1, loc2;; // Comparo r con i, salto mientras no r<i
     (p2)br.cond.dptk.many ciclo2;; // Salto a ciclo2
  // FinCiclo2

  add loc2= 1, loc2;; // Incremento el i
  cmp.eq p2, p1= loc2, in0;; // Comparo
  (p1) br.cond.dptk.many ciclo1;; // Salto si el i todavia no llego a n
// FinCiclo1

mov ar.pfs=loc0;;
mov r8 = 1;
br.ret.sptk.many b0;;
.endp coll

.proc oper
oper:
alloc loc0= ar.pfs, 1, 3, 0, 0;;
and loc1= 1, in0;;
cmp.eq p1,p2= 0, loc1;; // Levanta p1 si es par, p2 si impar

// Si es par
(p1)shl in0= in0, 1;;

// Si es impar
(p2)add loc2= in0, in0;;
(p2)add in0= loc2, in0, 1;;

mov r8= loc0;;
mov ar.pfs= loc0;;
br.ret.sptk.many b2;;
.endp oper