Ejercicios varios Itanium (Organización del Computador II)

De Cuba-Wiki
Revisión del 02:40 10 oct 2006 de 200.89.143.137 (discusión) (→‎Suma)
(difs.) ← Revisión anterior | Revisión actual (difs.) | Revisión siguiente → (difs.)

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

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.

.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 de Fibonacci

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.

.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