Buscar

Mars_Exemplos

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

row-major.asm
#############################################################################
# Row-major order traversal of 16 x 16 array of words.
# Pete Sanderson
# 31 March 2007
#
# To easily observe the row-oriented order, run the Memory Reference
# Visualization tool with its default settings over this program.
# You may, at the same time or separately, run the Data Cache Simulator 
# over this program to observe caching performance. Compare the results
# with those of the column-major order traversal algorithm.
#
# The C/C++/Java-like equivalent of this MIPS program is:
# int size = 16;
# int[size][size] data;
# int value = 0;
# for (int row = 0; col < size; row++) {
# for (int col = 0; col < size; col++) }
# data[row][col] = value;
# value++;
# }
# }
#
# Note: Program is hard-wired for 16 x 16 matrix. If you want to change this,
# three statements need to be changed.
# 1. The array storage size declaration at "data:" needs to be changed from
# 256 (which is 16 * 16) to #columns * #rows.
# 2. The "li" to initialize $t0 needs to be changed to new #rows.
# 3. The "li" to initialize $t1 needs to be changed to new #columns.
#
 .data
data: .word 0 : 256 # storage for 16x16 matrix of words
 .text
 li $t0, 16 # $t0 = number of rows
 li $t1, 16 # $t1 = number of columns
 move $s0, $zero # $s0 = row counter
 move $s1, $zero # $s1 = column counter
 move $t2, $zero # $t2 = the value to be stored
# Each loop iteration will store incremented $t1 value into next element of matrix.
# Offset is calculated at each iteration. offset = 4 * (row*#cols+col)
# Note: no attempt is made to optimize runtime performance!
loop: mult $s0, $t1 # $s2 = row * #cols (two-instruction sequence)
 mflo $s2 # move multiply result from lo register to $s2
 add $s2, $s2, $s1 # $s2 += column counter
 sll $s2, $s2, 2 # $s2 *= 4 (shift left 2 bits) for byte offset
 sw $t2, data($s2) # store the value in matrix element
 addi $t2, $t2, 1 # increment value to be stored
# Loop control: If we increment past last column, reset column counter and increment row counter
# If we increment past last row, we're finished.
 addi $s1, $s1, 1 # increment column counter
 bne $s1, $t1, loop # not at end of row so loop back
 move $s1, $zero # reset column counter
 addi $s0, $s0, 1 # increment row counter
 bne $s0, $t0, loop # not at end of matrix so loop back
# We're finished traversing the matrix.
 li $v0, 10 # system service 10 is exit
 syscall # we are outta here.
 
 
 
 
meu_primeiro_programa_MIPS.asm
# 
# Autor: Ney Calazans
# 
#	O objetivo deste programa é mostrar o uso mais básico da linguagem
#	de montagem do MIPS, através de um programa trivial que soma dois
#	números quaiquer de 32 bits (A e B no programa) armazenados em 
#	memória e coloca o resultado em uma terceira posição de memória
#	(C no programa). 
#
#	Note-se que este programa extremamente simples já serve para 
#	demonstrar várias das idiossincrasias de arquiteturas RISC, das quais
#	o MIPS é um exemplo clássico. Entre estas, cita-se:
#	1) A obtenção de um endereço de um dado em memória não pode ser
#	feita de forma simples por uma instrução. O montador SPIM supera 
#	esta limitação provendo uma pseudo-instrução (la) que será por ele 
#	traduzida durante a geração do código objeto para instruções da
#	arquitetura MIPS que desempenham este papel (uma seqüência de duas
#	instruções, lui e ori)
#	2) O uso de endereçamento base-deslocamento para fazer acesso a
#	qualquer dado em memória. Não existem instruções no MIPS que usem 
#	endereçamento direto para acesso a memória, sendo necessário partir
#	de um endereço base e especificar um deslocamento sobre este, que pode
#	obviamente simular endereçamento direto, se o deslocaamento for 0.
#	3) O uso da instrução jr para retornar do programa, salientando o
#	fato de que programas escritos operam como subrotinas chamadas pelo
#	núcleo (kernel) do ambiente SPIM.
#
 .text 
 .globl main 
 
main: la	$t0,A		# Carrega endereço de A em $t0 - PSEUDO-INSTRUÇÃO
	lw	$t0,0($t0)	# Lê valor de A para $t0
	la	$t1,B		# Carrega endereço de B em $t1 - PSEUDO-INSTRUÇÃO
	lw	$t1,0($t1)	# Lê valor de B para $t1
	addu	$t0,$t0,$t1	# $t0 recebe A+B
	la	$t2,C		# Carrega endereço de C em $t2 - PSEUDO-INSTRUÇÃO
	sw	$t0,0($t2)	# C recebe A+B
	
	# The program is finished. Exit.
	li	$v0,10		# system call for exit
	syscall			# Exit!
		
	
	
	.data
A:	.word	32
B:	.word	0xffab3400
C:	.word	0
 
Fibonacci.asm
# Compute several Fibonacci numbers and put in array, then print
.data
fibs:.word 0 : 19 # "array" of words to contain fib values
size: .word 19 # size of "array" (agrees with array declaration)
prompt: .asciiz "How many Fibonacci numbers to generate? (2 <= x <= 19)"
.text
 la $s0, fibs # load address of array
 la $s5, size # load address of size variable
 lw $s5, 0($s5) # load array size
# Optional: user inputs the number of Fibonacci numbers to generate
pr: la $a0, prompt # load address of prompt for syscall
 li $v0, 4 # specify Print String service
 syscall # print the prompt string
 li $v0, 5	 # Replace_this_dummy_with_the_correct_numeric_value??????? # specify Read Integer service
 syscall # Read the number. After this instruction, the number read is in $v0.
 bgt $v0, $s5, pr # Check boundary on user input -- if invalid, restart
 blt $v0, $zero, pr # Check boundary on user input -- if invalid, restart
 add $s5, $v0, $zero # transfer the number to the desired register
 
 li $s2, 1 # 1 is the known value of first and second Fib. number
 sw $s2, 0($s0) # F[0] = 1
 sw $s2, 4($s0) # F[1] = F[0] = 1
 addi $s1, $s5, -2 # Counter for loop, will execute (size-2) times
 
 # Loop to compute each Fibonacci number using the previous two Fib. numbers.
loop: lw $s3, 0($s0) # Get value from array F[n-2]
 lw $s4, 4($s0) # Get value from array F[n-1]
 add $s2, $s3, $s4 # F[n] = F[n-1] + F[n-2]
 sw $s2, 8($s0) # Store newly computed F[n] in array
 addi $s0, $s0, 4 # increment address to now-known Fib. number storage
 addi $s1, $s1, -1 # decrement loop counter
 bgtz $s1, loop # repeat while not finished
 
 # Fibonacci numbers are computed and stored in array. Print them.
 la $a0, fibs # first argument for print (array)
 add $a1, $zero, $s5 # second argument for print (size)
 jal print # call print routine. 
 # The program is finished. Exit.
 li $v0, 10 # system call for exit
 syscall # Exit!
		
###############################################################
# Subroutine to print the numbers on one line.
 .data
space:.asciiz " " # space to insert between numbers
head: .asciiz "The Fibonacci numbers are:\n"
 .text
print:add $t0, $zero, $a0 # starting address of array of data to be printed
 add $t1, $zero, $a1 # initialize loop counter to array size
 la $a0, head # load address of the print heading string
 li $v0, 4 # specify Print String service
 syscall # print the heading string
 
out: lw $a0, 0($t0) # load the integer to be printed (the current Fib. number)
 li $v0, 1 # specify Print Integer service
syscall # print fibonacci number
 
 la $a0, space # load address of spacer for syscall
 li $v0, 4 # specify Print String service
 syscall # print the spacer string
 
 addi $t0, $t0, 4 # increment address of data to be printed
 addi $t1, $t1, -1 # decrement loop counter
 bgtz $t1, out # repeat while not finished
 
 jr $ra # return from subroutine
# End of subroutine to print the numbers on one line
###############################################################
fatorial.asm
#
# MORAES - 23/agosto/2006
#
# Programa que calcula o fatorial de um número inteiro sem sinal.
#	Chama a função fact, que faz todo o trabalho
#	O argumento para fact é passado via o registrador de argumento
#	$a0. fact é uma função recursiva. Ela retorna o resultado de
#	seu processamento no registrador de valor $v0.
#
# main()
# {
#		int num=3;
#		int result=0;
#		result = fact(num);
# }
#
# int fact (int n)
# {
#		if(n<1)
#		return 1;
#		return (n * fact (n - 1));
# }
#
#
.data
 num: 		.word 0x0a
 result:	.word 0
.text
 .globl main
main:	la	$t0,num
		lw	$a0,0($t0)		# $a0 contém o número cujo fatorial deve ser calculado 
 
		addiu	$sp,$sp,-4	# Aloca espaço na pilha para 1 palavra (4 bytes)
		sw	$ra,0($sp)		# Salva o $ra no topo da pilha
 
		jal	fact			# Chama a função recursiva fact(num)
							# RESULTADO do fatorial deve retornar em $v0 
		lw	$ra,0($sp)		# Recupera o endereço de retorno
		addiu	$sp,$sp, 4
		la	$t0,result		# escreve resultado na variável
		sw	$v0,0($t0)		# result
		
		# The program is finished. Exit.
		li 	$v0, 10			# system call for exit
		syscall				# Exit!
		
fact:	addiu 	$sp,$sp,-8	# Início da função fact. Aloca 8 bytes na pilha
		sw	$ra,0($sp)		# Salva o endereço de retorno na pilha
		sw	$a0,4($sp)		# Salva o número cujo fatorial se quer calcular na pilha
 		
		sltiu	$t0,$a0, 1	# $t0=1 se num<1 
		beq	$t0,$zero,rec	# Se num>=1 ($t0=0), continua recursão
		addiu	$v0,$zero,1	# Se está no fim da recursão retorne fact(1)=1
		lw	$ra, 0($sp)		# Recupera o endereço de retorno
		addiu	$sp,$sp,8	# esvazia a pilha
		jr	$ra				# RETORNA por aqui na folha da recursão.
rec:	addiu	$a0 $a0,-1	# Se não está na folha da recursão, decrementa n
		jal	fact			# chama fact(num-1), RECURSIVAMENTE
		lw	$a0,4($sp)		# Na volta da recursão, recupera num
		lw	$ra,0($sp)		# recupera endereço de retorno 
		addiu	$sp,$sp,8	# restaura a pilha
		multu	$v0, $a0	# multiplica fact(num-1) ($v0) por num ($a0)
							# lembrar que resultado da multiplicação vai para
							# registradores hi e lo. Aqui, despreza-se parte alta
		mflo	$v0			# Assume-se que hi=0 e usa-se apena lo como resultado
							# Assim, $v0 e lo contêm fact(num)
		jr	$ra				# Retorna ao programa que chamou
Ex_Arquivo.asm
# Sample MIPS program that writes to a new file.
# by Kenneth Vollmar and Pete Sanderson
 .data
fout: .asciiz "testout.txt" # filename for output
buffer: .asciiz "The quick brown fox jumps over the lazy dog."
 .text
 ###############################################################
 # Open (for writing) a file that does not exist
 li $v0, 13 # system call for open file
 la $a0, fout # output file name
 li $a1, 1 # Open for writing (flags are 0: read, 1: write)
 li $a2, 0 # mode is ignored
 syscall # open a file (file descriptor returned in $v0)
 move $s6, $v0 # save the file descriptor 
 ###############################################################
 # Write to file just opened
 li $v0, 15 # system call for write to file
 move $a0, $s6 # file descriptor 
 la $a1, buffer # address of buffer from which to write
 li $a2, 44 # hardcoded buffer length
 syscall # write to file
 ###############################################################
 # Close the file 
 li $v0, 16 # system call for close file
 move $a0, $s6 # file descriptor to close
 syscall # close file
 ###############################################################
column-major.asm
################################################################
#
# Column-major order traversal of 16 x 16 array of words.
# Pete Sanderson
# 31 March 2007
#
# To easily observe the column-oriented order, run the Memory Reference
# Visualization tool with its default settings over this program.
# You may, at the same time or separately, run the Data Cache Simulator 
# over this program to observe caching performance. Compare the results
# with those of the row-major order traversal algorithm.
#
# The C/C++/Java-like equivalent of this MIPS program is:
# int size = 16;
# int[size][size] data;
# int value = 0;
# for (int col = 0; col < size; col++) {
# for (int row = 0; row < size; row++) }
# data[row][col] = value;
# value++;
# }
# }
#
# Note: Program is hard-wired for 16 x 16 matrix. If you want to change this,
# three statements need to be changed.
# 1. The array storage size declaration at "data:" needs to be changed from
# 256 (which is 16 * 16) to #columns * #rows.
# 2. The "li" to initialize $t0 needs to be changed to the new #rows.
# 3. The "li" to initialize $t1 needs to be changed to the new #columns.
#
 .data
data: .word 0 : 256 # 16x16 matrix of words
 .text
 li $t0, 16 # $t0 = number of rows
 li $t1, 16 # $t1 = number of columns
 move $s0, $zero # $s0 = row counter
 move $s1, $zero # $s1 = column counter
 move $t2, $zero # $t2 = the value to be stored
# Each loop iteration will store incremented $t1 value into next element of matrix.
# Offset is calculated at each iteration. offset = 4 * (row*#cols+col)
# Note: no attempt is made to optimize runtime performance!
loop: mult $s0, $t1 # $s2 = row * #cols (two-instruction sequence)
 mflo $s2 # move multiply result from lo register to $s2
 add $s2, $s2, $s1 # $s2 += col counter
 sll $s2, $s2, 2 # $s2 *= 4 (shift left 2 bits) for byte offset
 sw $t2, data($s2) # store the value in matrix element
 addi $t2, $t2, 1 # increment value to be stored
# Loop control: If we increment past bottom of column, reset row and increment column 
# If we increment past the last column, we're finished.
 addi $s0, $s0, 1 # increment row counter
 bne $s0, $t0, loop # not at bottom of column so loop back
 move $s0, $zero # reset row counter
 addi $s1, $s1, 1 # increment column counter
 bne $s1, $t1, loop # loop back if not at end of matrix (past the last column)
# We're finished traversing the matrix.
 li $v0, 10 # system service 10 is exit
 syscall # we are outta here.

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Outros materiais