1 + 2 + 3 + 4 + ⋯ + N

/**
 * @file    somatorio_1_n.s
 * @author  Halley Pacheco de Oliveira
 * @version 1.0
 * 
 * @section DESCRIPTION
 *
 * Programa para calcular o somatório dos números naturais de 1 a N.
 *
 * Usa as funções 'strtoi' e 'itostr' descritas no GitHub Gist
 * seenaburns/strtoi-add-argv.s
 * https://gist.github.com/seenaburns/70019f3217ab6392c3c245976e336978
 *
 * @param  Último número da série (N)
 * @output Número fornecido e o valor do somatório
 *
 * @see Wikipedia 1 + 2 + 3 + 4 + ⋯
 */

// Raspberry Pi 3 Modelo A+
.cpu	cortex-a53
.fpu	neon-fp-armv8
.syntax	unified 				// Sintaxe moderna

// Equates

.equ	SYS_EXIT, 1
.equ	SYS_WRITE, 4
.equ	STDIN, 0
.equ	STDOUT, 1

// Dados

.data

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

.align 4
txt_erro:	.string	"Erro: Informe o último número do somatório.\n"
.equ		TAM_ERRO, (. - txt_erro)	// Tamanho da mensagem de erro

.align 4
txt_over:	.string "Erro: valor máximo para o somatório excedido.\n"
.equ		TAM_OVER, (. - txt_over)	// Tamanho da mensagem de overflow

.align 4
result:		.space 32			// Espaço para o resultado do somatório

.text
.global _start

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	// Valor do destino 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
endnl:	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

msg_erro:			// Escreve a mensagem de erro na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Valor do destino em R0 (saída padrão, 1)
	LDR	R1, =txt_erro	// R1 -> texto da mensagem de erro
	MOV	R2, #TAM_ERRO	// Tamanho da string da mensagem de erro em R2
	SVC	0		// Chamar o sistema operacional
enderr:	MOV	PC, LR		// Retornar: PC (Program Counter) = LR (Link Register)

strsize:			// Calcula o tamanho da string e retorna em R2
	MOV	R4, R1		// R4 aponta para o 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)


overflow:			// Escreve a mensagem de overflow na saída padrão
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Valor do destino em R0 (saída padrão, 1)
	LDR	R1, =txt_over	// R1 -> texto da mensagem de erro
	MOV	R2, #TAM_OVER	// Tamanho da string da mensagem de erro em R2
	SVC	0		// Chamar o sistema operacional
	B	end		// Terminar a execução do programa

_start:

	LDR	R0, [SP]	// Número de argumentos (argc)
	CMP	R0, #1		// Número de argumentos = 1 ? (só o nome do programa?)
	BGT	argv0		// Se for maior continuar a execução do programa
	BL	msg_erro	// Se não for maior mostrar a mensagem de erro
	B	end		// e terminar o programa
	
argv0:				// Mostra argv[0] (nome do programa)
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Valor do destino em R0 (saída padrão, 1)
	LDR	R1, [SP, #4]	// argv[0] -> nome do programa
	BL	strsize		// Armazenar o tamanho do argumento em R2
	SVC	0		// Chamar o sistema operacional
	BL	nova_linha	// Avançar uma linha na saída padrão

argv1:				// Mostra argv[1] (N)
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Valor do destino em R0 (saída padrão, 1)
	LDR	R1, [SP, #8]	// argv[1] -> string contendo N
	BL	strsize		// Armazenar o tamanho do argumento em R2
	SVC	0		// Chamar o sistema operacional
	BL	nova_linha	// Avançar uma linha na saída padrão

somatorio:			// R1 = Somatório de 1 a N
	LDR	R0, [SP, #8]	// R0 -> limite do somatório (N)
	BL	strtoi		// Converter a string em um número inteiro
	MOV	R1, #0		// Inicializar o somatório como 0 em R1
somar:	ADDS	R1, R1, R0	// SOMA += N
	BVS	overflow	// Capacidade excedida
	SUBS	R0, R0, #1	// N -= 1
	BNE	somar		// Se N for diferente de zero então continuar

converter:			// Converter o somatório em string e mostrar
	MOV	R0, R1		// R0 = Somatório
	LDR	R1, =result	// R1 -> Valor convertido
	BL	itostr		// Converter inteiro em string

mostrar_convertido:		// Mostrar o somatório convertido em string
	LDR	R7, =SYS_WRITE	// Número da chamada do sistema em R7 (escrever)
	LDR	R0, =STDOUT	// Valor do destino em R0 (saída padrão, 1)
	LDR	R1, =result	// R1 -> string contendo o somatório em ASCII
	BL	strsize		// Armazenar o tamanho do resultado em R2
	SVC	0		// Chamar o sistema operacional
	BL	nova_linha	// Avançar uma linha na saída padrão

end:

	MOV	R7, #1		// Número da chamada do sistema em R7 (terminar)
	SVC	0		// Chamar o sistema operacional

Makefile:

somatorio_1_n: somatorio_1_n.o strtoi.o itostr.o
	ld -o somatorio_1_n somatorio_1_n.o strtoi.o itostr.o
somatorio_1_n.o: somatorio_1_n.s
	as -o somatorio_1_n.o somatorio_1_n.s
strtoi.o: strtoi.s
	as -o strtoi.o strtoi.s
itostr.o: strtoi.s
	as -o itostr.o itostr.s
clean:
	rm *.o  somatorio_1_n

Construção e execução:

pi@raspberrypi:~/assembly/somatorio_1_n $ make clean
rm *.o  somatorio_1_n
pi@raspberrypi:~/assembly/somatorio_1_n $ make
as -o somatorio_1_n.o somatorio_1_n.s
as -o strtoi.o strtoi.s
as -o itostr.o itostr.s
ld -o somatorio_1_n somatorio_1_n.o strtoi.o itostr.o
pi@raspberrypi:~/assembly/somatorio_1_n $ ./somatorio_1_n
Erro: Informe o último número do somatório.
pi@raspberrypi:~/assembly/somatorio_1_n $ ./somatorio_1_n 65535
./somatorio_1_n
65535
2147450880
pi@raspberrypi:~/assembly/somatorio_1_n $ ./somatorio_1_n 131071
./somatorio_1_n
131071
Erro: valor máximo para o somatório excedido.

↑ Acima