ccufcg / oac24.1

OAC 2024.1
GNU General Public License v3.0
1 stars 0 forks source link

GRUPO 04 #4

Open nobregat opened 1 month ago

josetruta commented 1 month ago

Código em .asm para execução:

# Verifica se um determinado número é par.
addi x1, x0, 30 # Adiciona o número a ser verificado em x1.
addi x7, x0, 1 # Adiciona o valor 1 em x7.
addi x6, x0, 2 # Adiciona o valor 2 em x6.
add x2, x0, x1 # Faz cópia do número a ser verificado em x2, para iteração.
loop: 
    beq x2, x0, true # Se o número resultante for igual à 0, é par.
    beq x2, x7, false # Se o número resultante for igual à 1, é ímpar.
    sub x2, x2, x6 # Subtrai 2 do número em verificação.
    jal x0, loop  # Retorna ao ínicio do loop.
true:
    addi x3, x0, 1 # Caso seja par, adiciona 1 em x3.
    nop # Encerra execução.
false:
    nop # Encerra execução.

O algoritmo acima é uma forma iterativa de verificar se um número é par. Dado um certo número, armazenado no registrador x1, é subtraído de 2 em 2 deste; há duas condições de paradas: esta sucessão de subtrações dar 0, indicando que o número é par; ou as subtrações resultarem em 1, indicando que o número é ímpar. O resultado booleano é armazenado no registrador x3.

josetruta commented 1 month ago

Instruções em binário gerado por nosso compilador:

00000001111000000000000010010011 00000000000100000000001110010011 00000000001000000000001100010011 00000000000100000000000100110011 00000000000000010000100001100011 00000000011100010000101001100011 01000000011000010000000100110011 00000000000000000100000001101111 00000000000100000000000110010011 00000000000000000000000000010011 00000000000000000000000000010011

josetruta commented 1 month ago

Resultado da simulação em nosso algoritmo, com os estados do PC e registradores:

PC: 36 r0: 0 r1: 30 r2: 0 r3: 1 r4: 0 r5: 0 r6: 2 r7: 1

DeboraSabrinaOPereira commented 1 month ago

Testamos o assembly no nosso compilador e a saída produzida foi quase a mesma, a única diferença foi da operação "jal" porque estamos tratando o desvio de fluxo de forma diferente. Fazemos o cálculo assim (linha do rótulo - linha da chamada ao rótulo), que acaba resultando em um número negativo (salto para trás) e estamos tratando isso com complemento de dois.

EmanuelSal commented 1 month ago

Também testamos o assembly, o resultado deu o mesmo nos registradores. Apenas o PC que deu diferente. Não sabemos ao certo onde está a incoerência (No nosso compilador ou no de vocês).

Nosso PC: 11 PC de vocês: 36

Talvez essa diferença seja na maneira de tratar os bits. Pelo que vimos, vocês tratam os bits de 4 em 4, Já no nosso, tratamos 1 a 1

erikdionisio commented 1 month ago

O motivo do nosso PC ser incrementado em 4 a cada instrução executada, é para simular o avanço para o próximo endereço de memoria já que cada instrução RISC-V tem um tamanho fixo de 32 bits (ou 4 bytes). Isso significa que, a cada ciclo de instrução, o PC avança para o próximo endereço da memória de instrução, que é 4 bytes à frente do atual.

DeboraSabrinaOPereira commented 1 month ago

Gente, o jal de vocês segue essa padronização do formato da instrução?

image

Porque mudamos o nosso cálculo do jal e a única linha diferente novamente foi a dessa instrução. Aparentemente o valor do salto é o mesmo, mas a forma de "distribuir" ele na instrução ficou diferente.