Wolfram Mathematica Matriz Transposta

Transposição de matriz de inteiros

/*
 * Programa para realizar a transposição de uma matriz.
 *
 * A matriz transposta é obtida trocando-se as linhas pelas colunas
 * de uma dada matriz.
 *
 * Matriz original    Matriz Transposta
 *    | 1 2 |          | 1 3 5 7 |
 *    | 3 4 |          | 2 4 6 8 |
 *    | 5 6 |
 *    | 7 8 |
 *
 * Tanto a matriz original quanto a matriz transposta são mostradas
 * na saída padrão.
 *
 * Usa a função 'itostr' descritas no GitHub Gist
 * seenaburns/strtoi-add-argv.s
 * https://gist.github.com/seenaburns/70019f3217ab6392c3c245976e336978
 */

// Raspberry Pi 3 Modelo A+
.cpu	cortex-a53
.fpu	neon-fp-armv8
.syntax	unified 		// Unified Assembler Language

// Equivalências

.equ	SYS_EXIT, 1
.equ	SYS_WRITE, 4
.equ	STDIN, 0
.equ	STDOUT, 1
.equ	STDERR, 2
.equ	LINHAS, 4
.equ	COLUNAS, 2

// Macro

.macro mostrar_matriz matriz, linhas, colunas
	MOV	R8, #0		// R8 = Número da Linha = I
	MOV	R9, #0		// R9 = Número da Coluna = J
	MOV	R10, #4		// R10 = Tamanho em bytes do número inteiro
giro\@:	PUSH	{R8, R9}	// Loop nos elementos da matriz
	MOV	R5, #\colunas	// R5 = número de colunas
	MLA	R6, R8, R5, R9	// R6 = Posição na matriz = J + (I x COLUNAS)
	MUL	R6, R10		// R6 = Deslocamento na matriz em bytes
	LDR	R0, =\matriz	// R0 -> Início da matriz
	ADD	R0, R0, R6	// R0 -> Posição do elemento na matriz
	LDR	R0, [R0]	// R0 = Valor do elemento da matriz
	LDR	R1, =valor	// R1 -> String contendo o valor convertido
	BL	itostr		// Converter inteiro em string
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Descritor do arquivo em R0 (saída padrão, 1)
	LDR	R1, =valor	// R1 -> String contendo o valor convertido
	BL	strsize		// Armazenar o tamanho do resultado em R2
	SVC	0		// Chamar o sistema operacional
	BL	tabular		// Tabular a saída padrão
	POP	{R8,R9}		// Restaurar o nº da linha e o nº da coluna
	ADD	R9, #1		// Próxima coluna
	CMP	R9, #\colunas	// Comparar o nº da coluna com o nº de colunas
	BLT	giro\@		// Se for menor mostrar a próxima coluna
	BL	nova_linha	// Senão avançar uma linha na saída padrão
	MOV	R9, #0		// R9 = Número da coluna = Primeira coluna
	ADD	R8, #1		// R8 = Próxima linha
	CMP	R8, #\linhas	// Comparar o nº da linha com o nº de linhas
	BLT	giro\@		// Se for menor mostrar a próxima linha
.endm

// Dados

.data

.align

m:	.word 1, 2		// m = Matriz original (4x2)
	.word 3, 4
	.word 5, 6
	.word 7, 8

t:	.word 0, 0, 0, 0	// t = Matriz transposta de m (2x4)
	.word 0, 0, 0, 0

.align
new_line:	.string	"\n"	// Caracter de nova linha

.align
tab:		.string	"\t"	// Caracter de tabulação

.align
txt_orig:	.string "Matriz original:\n"
.equ		TAM_ORIG, (. - txt_orig)	// Tamanho da mensagem

.align
txt_transp:	.string "Matriz transposta:\n"
.equ		TAM_TRANSP, (. - txt_transp)	// Tamanho da mensagem

.align
valor:		.space 32	// Espaço para o valor formatado

// Código

.text
.global _start

strsize:			// Calcula o tamanho da string e retorna em R2
	MOV	R4, R1		// R4 -> início da string apontada por R1
	MOV	R2, #0		// Inicializa o tamanho da string com 0
loop:	LDRB	R3,[R4], #1	// Carrega o byte apontado por R4 em R3; R4 += 1
	CMP	R3, #0		// Compara o valor em R3 com 0 (fim da string)
	BEQ	endl		// Se for igual sai do loop e retorna
	ADD	R2, #1		// Senão incrementa o tamanho da string em R2
	B	loop		// e continua o loop
endl:	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

nova_linha:			// Escreve o caracter de nova linha na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Descritor do arquivo em R0 (saída padrão, 1)
	LDR	R1, =new_line	// R1 -> string de nova linha
	MOV	R2, #1		// Tamanho da string em R2 (um)
	SVC	0		// Chamar o sistema operacional
	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

tabular:			// Escreve o caracter de tabulação na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Descritor do arquivo em R0 (saída padrão, 1)
	LDR	R1, =tab	// R1 -> string de tabulação
	MOV	R2, #1		// Tamanho da string em R2 (um)
	SVC	0		// Chamar o sistema operacional
	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

msg_orig:			// Escreve a mensagem de matriz original na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Descritor do arquivo em R0 (saída padrão, 1)
	LDR	R1, =txt_orig	// R1 -> texto da mensagem
	MOV	R2, #TAM_ORIG	// Tamanho da string da mensagem em R2
	SVC	0		// Chamar o sistema operacional
	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

msg_transp:			// Escreve a mensagem de matriz transposta na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Descritor do arquivo em R0 (saída padrão, 1)
	LDR	R1, =txt_transp	// R1 -> texto da mensagem
	MOV	R2, #TAM_TRANSP	// Tamanho da string da mensagem em R2
	SVC	0		// Chamar o sistema operacional
	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

_start:

#	Mostrar a matriz original
	BL	msg_orig	// Mostrar a mensagem de matriz original
	mostrar_matriz m, LINHAS, COLUNAS

#	Transposição da matriz
	MOV	R8, #0		// R8 = Número da Linha = I
	MOV	R9, #0		// R9 = Número da Coluna = J
	MOV	R10, #4		// R10 = Tamanho em bytes do número inteiro
prox:				// Loop nos elementos da matriz original
	MOV	R5, #COLUNAS	// R5 = número de colunas da matriz original
	MLA	R6, R8, R5, R9	// R6 = Posição na matriz = J + (I x COLUNAS)
	MUL	R6, R10		// R6 = Deslocamento na matriz em bytes
	LDR	R0, =m		// R0 -> Início da matriz original
	ADD	R0, R0, R6	// R0 -> Posição do elemento na matriz original
	LDR	R0, [R0]	// R0 = Valor do elemento da matriz original
				// Matriz Transposta
	MOV	R5, #LINHAS	// R5 = número de colunas da matriz transposta
	MLA	R6, R9, R5, R8	// R6 = Posição na matriz = I + (J x LINHAS)
	MUL	R6, R10		// R6 = Deslocamento na matriz em bytes
	LDR	R1, =t		// R1 -> Início da matriz transposta
	ADD	R1, R1, R6	// R1 -> Posição do elemento na matriz
	STR	R0, [R1]	// Armanenar o valor na matriz transposta
				// Próximo elemento da matriz original
	ADD	R9, #1		// Próxima coluna da matriz original
	CMP	R9, #COLUNAS	// Comparar o nº da coluna com o nº de colunas
	BLT	prox		// Se for menor processar a próxima coluna
	MOV	R9, #0		// R9 = Número da coluna = 0 = Primeira coluna
	ADD	R8, #1		// R8 = Próxima linha
	CMP	R8, #LINHAS	// Comparar o nº da linha com o nº de linhas
	BLT	prox		// Se for menor processar para a próxima linha

#	Mostrar a matriz transposta
	BL	msg_transp	// Mostrar a mensagem de matriz transposta
	mostrar_matriz t, COLUNAS, LINHAS

end:

	MOV	R7, #SYS_EXIT	// Número da chamada do sistema em R7 (terminar)
	MOV	R0, #0		// Código de retorno igual a zero
	SVC	0		// Chamar o sistema operacional

Makefile:

mat_transp_int: mat_transp_int.o itostr.o
	ld -o mat_transp_int mat_transp_int.o itostr.o
mat_transp_int.o: mat_transp_int.s
	as -o mat_transp_int.o mat_transp_int.s
itostr.o: itostr.s
	as -o itostr.o itostr.s
clean:
	rm *.o  mat_transp_int

Construção e execução:

pi@raspberrypi:~/assembly/mat_transp_int $ make clean
rm *.o  mat_transp_int
pi@raspberrypi:~/assembly/mat_transp_int $ make
as -o mat_transp_int.o mat_transp_int.s
as -o itostr.o itostr.s
ld -o mat_transp_int mat_transp_int.o itostr.o
pi@raspberrypi:~/assembly/mat_transp_int $ ./mat_transp_int
Matriz original:
1	2	
3	4	
5	6	
7	8	
Matriz transposta:
1	3	5	7	
2	4	6	8	

↑ Acima