Baixe o app para aproveitar ainda mais
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.
Compartilhar