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 1 times 7 ou 7 times 1.

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

Exercícios relacionados