Desenvolva um código em Assembly para família MCS51 que leia uma lista de oito números e informe no registrador R1 qual o maior número da lista, no registrador R0 qual o menor valor e no registrador R2 a quantidade de valores da lista que são números primos*.
Usar como base o exemplo abaixo
// Aponta para inicio da lista
MOV DPTR, #LISTA
//Move para A índice da lista
MOV A, #0
// Le valor
MOVC A, @A+DPTR
// Seu código …
LISTA:
DB 23, 8, 10, 68, 31, 17, 9,36
END
- Um número primo é um número natural maior que 1 que não pode ser formado pela multiplicação de outros dois naturais menores. Por exemplo, 7 é primo porque só pode ser formado por
ou
.
Usar como base o exemplo abaixo
// Aponta para inicio da lista
MOV DPTR, #LISTA
//Move para A índice da lista
MOV A, #0
// Le valor
MOVC A, @A+DPTR
// Seu código …
LISTA:
DB 23, 8, 10, 68, 31, 17, 9,36
END
Passo 1
Beleza, vamos lá! O exercício pede pra gente escrever um código em Assembly pra família MCS51 que leia uma lista de oito números. A gente tem que encontrar o maior número e guardar no registrador R1, o menor número no R0, e contar quantos desses números são primos, guardando esse número em R2. Pra resolver isso, vamos precisar entender como manipular listas em Assembly, usar loops pra comparar os números e uma lógica pra verificar se um número é primo.
Passo 2
Primeiro, vamos configurar o ponteiro de dados (DPTR) para apontar pro início da lista de números. Isso facilita a gente acessar cada número da lista sequencialmente.
MOV DPTR, #LISTA ; Aponta pro início da lista
Passo 3
Vamos inicializar os registradores que vão guardar o maior, o menor e a contagem de números primos. Vamos pegar o primeiro número da lista como inicial maior e menor, e começar a contagem de primos em zero.
MOVC A, @A+DPTR ; Move o primeiro valor da lista para o acumulador A
MOV R1, A ; Inicializa R1 com o primeiro número (maior)
MOV R0, A ; Inicializa R0 com o primeiro número (menor)
CLR R2 ; Zera o contador de primos
Passo 4
Agora, vamos criar um loop que vai percorrer os próximos sete números da lista (já que o primeiro já foi usado para inicializar). Usaremos um registrador como índice para controlar quantas vezes o loop deve rodar.
MOV R3, #7 ; R3 vai contar quantos números faltam
Passo 5
Dentro do loop, vamos pegar cada número, comparar com o atual maior e menor, e verificar se é primo. A cada iteração, aumentamos o ponteiro pra pegar o próximo número.
LOOP:
MOVC A, @A+DPTR ; Pega o próximo número
; Verifica se é maior que R1
CJNE A, R1, CHECK_MAX
SJMP CHECK_MIN
CHECK_MAX:
JC NOT_MAX
MOV R1, A ; Atualiza o maior número
NOT_MAX:
; Verifica se é menor que R0
CJNE A, R0, CHECK_MIN
SJMP CHECK_PRIME
CHECK_MIN:
JC NOT_MIN
MOV R0, A ; Atualiza o menor número
NOT_MIN:
; Agora, vamos verificar se o número é primo
Passo 6
Para verificar se um número é primo, vamos dividir ele por todos os números menores que ele (começando de 2) e ver se tem algum que divide sem resto. Se não tiver, é primo.
; Verifica se A <= 1, não é primo
MOV B, A
CJNE A, #1, CHECK_DIV
SJMP NOT_PRIME
CHECK_DIV:
MOV R4, #2 ; Inicia divisão por 2
DIV_LOOP:
MOV A, B
DIV AB ; Divide B por R4
JC NOT_PRIME ; Se houver resto, não é primo
; Se R0 == 0, é divisível
MOV A, B
MOD PROC TO CHECK SE DIVISOR DIVIDE SEM RESTO
; Se não for divisível, continua
INC R4
CJNE R4, A, DIV_LOOP ; Continua até R4 < A
; Se passou por todas, é primo
INC R2
NOT_PRIME:
; Continua o loop principal
Passo 7
Depois de verificar se o número é primo e atualizar os registradores conforme necessário, decrementamos o contador do loop e verificamos se ainda tem números pra processar. Se tiver, volta pro início do loop.
DEC R3
JNZ LOOP ; Se ainda tem números, continua
Passo 8
Finalmente, quando o loop terminar, os registradores R1, R0 e R2 terão os valores desejados: o maior número, o menor número e a quantidade de números primos na lista.
Resposta
ORG 0000h ; Início do programa
START:
MOV DPTR, #LISTA ; Aponta para o início da lista
MOV A, #0 ; Índice inicial
MOVC A, @A+DPTR ; Move o primeiro valor para A
MOV R1, A ; R1 = Maior número
MOV R0, A ; R0 = Menor número
CLR R2 ; R2 = Contador de primos
MOV R3, #7 ; Restam 7 números para verificar
LOOP:
INC DPTR ; Move para o próximo número
MOVC A, @A+DPTR ; Move o próximo valor para A
; Verifica maior
MOV B, R1
CJNE A, B, CHECK_MAX
SJMP CHECK_MIN
CHECK_MAX:
JNC NOT_MAX
MOV R1, A ; Atualiza Maior
NOT_MAX:
; Verifica menor
MOV B, R0
CJNE A, B, CHECK_MIN
SJMP CHECK_PRIME
CHECK_MIN:
JNC NOT_MIN
MOV R0, A ; Atualiza Menor
NOT_MIN:
; Verifica se é primo
MOV B, A
CJNE A, #1, CHECK_DIV
SJMP NOT_PRIME
CHECK_DIV:
MOV R4, #2 ; Inicia divisor em 2
DIV_LOOP:
MOV A, B
DIV AB ; A/B -> A = Quociente, B = Resto
JNC DIV_CONTINUE ; Se não houve carry, continua
INC R2 ; É primo
SJMP END_CHECK
DIV_CONTINUE:
MOV A, R4
ADD A, #1
MOV R4, A
CJNE R4, B, DIV_LOOP
INC R2 ; É primo
END_CHECK:
NOT_PRIME:
DEC R3
JNZ LOOP
END_PROGRAM:
END
LISTA:
DB 23, 8, 10, 68, 31, 17, 9, 36