Escreva um programa em assembly para determinar a quantidade de zeros em uma palavra de 8 bits.
Passo 1
O enunciado pede um programinha em Assembly que conta quantos zeros existem numa palavra de 8 bits.
Matéria envolvida: operações bit-a-bit (AND, shift), laços (loop) e desvios condicionais em Assembly (no nosso caso, MIPS).
Para resolver isso a gente vai precisar de:
Matéria envolvida: operações bit-a-bit (AND, shift), laços (loop) e desvios condicionais em Assembly (no nosso caso, MIPS).
Para resolver isso a gente vai precisar de:
- Um registrador para guardar a palavra de 8 bits (vamos usar $t0).
- Um registrador para contar zeros (vamos usar $t1).
- Um registrador para contar quantos bits já analisamos (vamos usar $t2).
- Conhecer as instruções
andi
,srl
,beq
,blt
, além de como usar syscalls para imprimir o resultado.
Passo 2
Algoritmo de alto nível (pseudo-código):
- Carrega a palavra de 8 bits em um registrador.
- Zera o contador de zeros e o contador de bits processados.
- Enquanto não processar 8 bits:
a) Extrai o bit menos significativo (LSB) com AND (bit = n & 1
).
b) Se esse bit for 0, incrementa o contador de zeros.
c) Desloca a palavra 1 posição à direita (n = n >> 1
).
d) Incrementa o contador de bits processados. - No fim, o contador de zeros tem a resposta.
Passo 3
Teoria aplicada:
- Para extrair o LSB usamos a operação bit-a-bit AND:
Se, o LSB original era zero; se , o LSB era um.
- Para “varrer” cada bit da direita pra esquerda a gente faz um deslocamento lógico à direita:
Que em MIPS é srl $dest, $src, 1
. - O loop vai de 0 até 7 (8 iterações) — controlado por um registrador contador e um desvio condicional.
Passo 4
Vamos traduzir o pseudo-código para Assembly MIPS.
Registradores usados:
Registradores usados:
- $t0 : valor atual (8 bits)
- $t1 : contador de zeros
- $t2 : contador de bits processados
- $t3 : valor do AND (
n & 1
) - $t4 : constante 8 (número de bits)
Fluxo do programa:
- Carrega o byte de .data em $t0 usando
lbu
. - Inicializa $t1 e $t2 com zero e $t4 com 8.
- Define o rótulo
loop:
e dentro dele fazandi $t3,$t0,1
. - Se $t3 for igual a zero (
beq $t3,$zero,inc
), pula para incrementar $t1. - Depois de testar, faz
srl $t0,$t0,1
e incrementa $t2. - Usa
blt $t2,$t4,loop
para repetir até 8 bits. - Ao final, imprime $t1 com syscall e encerra.
Resposta
.data
palavra: .byte 0xA6 # Exemplo: 0xA6 = 166 = b10100110 (8 bits)
.text
.globl main
main:
# 1) Carrega a palavra de 8 bits (unsigned) em $t0
la $t0, palavra
lbu $t0, 0($t0)
# 2) Inicializa contadores
li $t1, 0 # contador de zeros
li $t2, 0 # contador de bits processados
li $t4, 8 # número total de bits
loop:
# 3) Extrai o bit menos significativo
andi $t3, $t0, 1
beq $t3, $zero, inc # se o bit = 0, vai incrementar contador
# se bit = 1, pula direto
next:
# 5) Desloca pra direita e incrementa bits processados
srl $t0, $t0, 1
addi $t2, $t2, 1
blt $t2, $t4, loop # repete até processar 8 bits
# 7) Imprime o resultado (quantidade de zeros em $t1)
move $a0, $t1
li $v0, 1 # syscall print_int
syscall
# Encerra o programa
li $v0, 10
syscall
inc:
# 4) Incrementa contador de zeros
addi $t1, $t1, 1
j next