Você está na página 1de 6

AD2 – Organização de Computadores

Nome: Joême Alves Ferreira Junior


Matricula: 22113050251

Questão 1) A aparente contradição entre a resposta do ChatGPT e a informação fornecida pelo site de Stanford se deve
à diferença de contexto e ênfase na discussão. Vamos esclarecer as diferenças e semelhanças entre as arquiteturas
CISC e RISC para ajudar a resolver essa contradição.

As arquiteturas CISC (Complex Instruction Set Computing) e RISC (Reduced Instruction Set Computing) possuem
abordagens diferentes para a execução de instruções em um processador.

A arquitetura CISC possui um conjunto maior de instruções complexas que podem executar várias operações em uma
única instrução. Essa abordagem visa simplificar a programação em linguagem de alto nível, permitindo que as
instruções correspondam mais diretamente às operações desejadas. Portanto, o compilador precisa fazer menos
trabalho para traduzir uma instrução de alto nível em código de montagem, resultando em um código-fonte mais curto.

Por outro lado, a arquitetura RISC utiliza um conjunto menor de instruções mais simples, com cada instrução
executando apenas uma operação básica. Essa abordagem simplifica o projeto do hardware e permite que as instruções
sejam executadas de forma mais eficiente. Embora o compilador precise fazer um pouco mais de trabalho para traduzir
as instruções de alto nível em código de montagem, o código resultante tende a ser mais compacto e eficiente.

A resposta do ChatGPT refere-se ao código objeto, ou seja, o código binário que é executado diretamente pelo
hardware do processador. Nesse sentido, a arquitetura CISC tende a gerar código objeto maior porque as instruções
são mais complexas e requerem mais espaço de memória para serem armazenadas. No entanto, essa maior ocupação
de memória ocorre devido ao maior número de instruções complexas disponíveis na arquitetura CISC, não
necessariamente devido ao comprimento do código-fonte.

Por outro lado, o material do site de Stanford menciona que o comprimento do código de montagem gerado pelo
compilador para a arquitetura CISC é relativamente curto, o que está correto. O foco nesse caso é sobre o comprimento
do código de montagem gerado pelo compilador, que é uma representação intermediária entre o código-fonte e o
código objeto. Esse código de montagem é mais curto porque as instruções de alto nível são mapeadas diretamente
para instruções complexas disponíveis na arquitetura CISC.

Em resumo, a arquitetura CISC pode gerar código objeto maior devido à presença de instruções complexas, mas o
código de montagem (uma representação intermediária) gerado pelo compilador pode ser mais curto porque as
instruções de alto nível se mapeiam diretamente para instruções complexas disponíveis na arquitetura CISC. É
importante distinguir entre o código-fonte, o código de montagem e o código objeto ao analisar as características e
desempenho das arquiteturas CISC e RISC.

Questão 2) Considere os seguintes três pseudo-códigos.

Pseudo-código 1:

1. Início
2. Configurar o dispositivo de entrada
3. Iniciar a leitura de dados do dispositivo
4. Aguardar até que a leitura seja concluída
5. Armazenar os dados lidos em um buffer de memória
6. Processar os dados lidos
7. Fim

Pseudo-código 2:

1. Início
2. Configurar o dispositivo de entrada
3. Configurar a rotina de tratamento de interrupção para a entrada do
dispositivo
4. Quando a interrupção ocorrer, o processador pausa a execução do
programa atual
5. A rotina de tratamento de interrupção é executada para lidar com os
dados de entrada
6. A rotina de tratamento de interrupção armazena os dados em um
buffer de memória
7. A rotina de tratamento de interrupção retorna o controle para o
programa principal
8. Processar os dados lidos
9. Fim

Pseudo-código 3:

1. Início
2. Configurar o controlador para a transferência de dados entre o
dispositivo e a memória
3. Configurar o dispositivo de entrada para a transferência de dados
4. Configurar os endereços de origem e destino da transferência de
dados
5. Configurar o tamanho da transferência de dados
6. Habilitar o início da transferência de dados
8. O controlador inicia a transferência de dados, sem a intervenção do
processador
9. O controlador emite uma interrupção para o processador quando a
transferência for concluída
10. Tratar a interrupção do controlador, se necessário
11. Processar os dados transferidos, quando desejado
12. Fim

a) (1,0 ponto) Qual o nome da abordagem de E/S usada pelo pseudocódigo 1, pelo pseudocódigo 2, e pelo
pseudocódigo 3? Qual a vantagem de cada uma delas em comparação com a anterior?

b) (2,0 pontos) Em cada uma das situações abaixo, indique qual pseudocódigo, ou quais pseudocódigos, são mais
aconselháveis, justificando claramente sua resposta em cada caso.

(i) Imagine uma aplicação lendo dados de um dispositivo de armazenamento em um momento crítico do processamento,
em que qualquer interrupção durante a leitura pode causar problemas de sincronização. A
aplicação deseja controlar o momento exato da leitura dos dados.

(ii) Considere uma aplicação que envolve operações de E/S em um ambiente de tempo real, em que a latência do sistema
é um fator crítico e que precisa ser minuciosamente controlado. Como no item anterior, não se deseja
usar nenhum tipo de interrupções.

(iii) Considere uma aplicação que necessite de E/S de forma assíncrona, ou seja, sem esperar que a operação termine
antes de continuar a execução. Isto ocorre, por exemplo, num laptop, ao ler dados do mouse.
(iv) Considere uma aplicação de alto desempenho, que precisa realizar transferências de grandes volumes de dados entre
dispositivos de E/S e a memória do sistema de forma eficiente e sem sobrecarga de processamento. Isto ocorre, por
exemplo, em aplicações de processamento de vídeo e áudio.

Resposta:
a) O pseudocódigo 1 utiliza a abordagem de E/S por polling, onde o programa verifica repetidamente se os dados de
entrada estão prontos para serem lidos. O pseudocódigo 2 utiliza a abordagem de E/S por interrupção, onde o programa
configura uma rotina de tratamento de interrupção que é executada quando ocorre uma interrupção do dispositivo de
entrada. O pseudocódigo 3 utiliza a abordagem de E/S por DMA (Direct Memory Access), onde o controlador de E/S
transfere os dados diretamente entre o dispositivo e a memória, sem a intervenção do processador.

A vantagem do pseudocódigo 1 em relação ao pseudocódigo 2 é que não há necessidade de lidar com interrupções, o
que pode simplificar o fluxo de controle do programa. No entanto, essa abordagem pode consumir mais tempo de
processamento, pois o programa precisa verificar repetidamente se os dados estão prontos.

A vantagem do pseudocódigo 2 em relação ao pseudocódigo 1 é que ele permite um controle mais preciso sobre o
momento da leitura dos dados. O programa pode pausar sua execução normal e lidar com os dados de entrada
imediatamente quando ocorre uma interrupção. Isso é especialmente útil em situações críticas de sincronização.

A vantagem do pseudocódigo 3 em relação aos pseudocódigos 1 e 2 é que ele transfere os dados diretamente entre o
dispositivo e a memória, sem a necessidade de intervenção do processador. Isso pode resultar em uma transferência mais
eficiente e com menor sobrecarga de processamento.

b) (i) No caso em que a aplicação deseja controlar o momento exato da leitura dos dados e qualquer interrupção durante
a leitura pode causar problemas de sincronização, o pseudocódigo mais aconselhável seria o pseudocódigo 1. Nessa
abordagem, a aplicação pode controlar diretamente a leitura dos dados, esperando até que a leitura seja concluída antes
de prosseguir com o processamento.

(ii) No caso de uma aplicação em ambiente de tempo real, em que a latência do sistema é crítica e não se deseja usar
interrupções, o pseudocódigo mais aconselhável seria o pseudocódigo 1. Nessa abordagem, a aplicação pode controlar
o momento exato da leitura dos dados e evitar interrupções que possam afetar a latência do sistema.

(iii) No caso de uma aplicação que necessita de E/S de forma assíncrona, sem esperar a conclusão da operação, o
pseudocódigo mais aconselhável seria o pseudocódigo 3. Com a abordagem de E/S por DMA, o controlador de E/S pode
transferir os dados diretamente para a memória, permitindo que a aplicação continue sua execução sem esperar pela
conclusão da operação de E/S.

(iv) No caso de uma aplicação de alto desempenho que precisa realizar transferências eficientes de grandes volumes de
dados, o pseudocódigo mais aconselhável seria o pseudocódigo 3. A abordagem de E/S por DMA permite transferências
diretas entre dispositivos de E/S e a memória, sem sobrecarregar o processador. Isso é especialmente útil em aplicações
de processamento de vídeo e áudio, pois essas aplicações geralmente lidam com grandes volumes de dados que precisam
ser transferidos de forma eficiente para garantir o desempenho adequado.

Nesse caso, o pseudocódigo 3, que utiliza a abordagem de E/S por DMA, permite que o controlador de E/S transfira os
dados diretamente entre o dispositivo e a memória, liberando o processador para realizar outras tarefas. Isso reduz a
sobrecarga de processamento e melhora o desempenho geral da aplicação, garantindo uma transferência rápida e
eficiente dos dados entre os dispositivos de E/S e a memória do sistema.

Portanto, para uma aplicação de alto desempenho que lida com transferências de grandes volumes de dados, o
pseudocódigo 3 é mais aconselhável.
Questão 3)

a) Para dividir um número inteiro por dois usando o deslocamento de bits, podemos utilizar a operação de deslocamento
binário para a direita (ou seja, deslocar os bits para a direita) uma posição. Isso é equivalente a dividir o número por 2

Para dividir um número inteiro por dois usando deslocamento de bits, temos que:

1. Pegar o número inteiro que deseja dividir.


2. Realizar um deslocamento binário para a direita em uma posição (equivalente a dividir por 2).

Assim o resultado obtido após o deslocamento é o quociente da divisão.

Se queremos dividir o número 5 por 2:

Representação binária de 5: 101

Deslocamento binário para a direita uma posição: 10

O resultado é 2, que é o quociente da divisão.

b) Se o número estiver em complemento de dois, o procedimento de divisão por dois usando o deslocamento de bits
ainda é válido. No complemento de dois, o deslocamento binário para a direita preserva o sinal do número, mantendo
o bit de sinal (o bit mais significativo) igual ao valor original.

No entanto, ao realizar o deslocamento binário para a direita em um número em complemento de dois, é importante
observar que o bit de sinal precisa ser replicado nos bits deslocados para a direita. Isso garante que o valor negativo
seja mantido corretamente ao realizar a divisão por dois.

Se temos o número -5 representado em complemento de dois:

Representação binária de -5 em complemento de dois: 1111111111111011

Deslocamento binário para a direita uma posição (replicando o bit de sinal): 1111111111111101

O resultado é -3, que é o quociente da divisão.

Portanto, ao realizar a divisão por dois usando o deslocamento de bits em um número em complemento de dois, é
necessário replicar o bit de sinal durante o deslocamento para manter corretamente o valor negativo.

Questão 4)

a) Para realizar a adição de A e B, considerando que ambos estão em complemento a 2, podemos usar a seguinte
operação:

A + B = A + (-B)

A = 01011110 B = 10011101 (negativo em complemento a 2)


Obtendo o negativo de B em complemento a 2: Negativo de B = Inverter todos os bits de B e adicionar 1 Negativo de
B = 01100011 + 1 = 01100100

Agora, realizamos a adição de A com o negativo de B: A + (-B) = 01011110 + 01100100 = 11000010

O resultado da adição é 11000010 em complemento a 2, que em decimal é -62.

b) Para realizar a subtração de B por A, também considerando que ambos estão em complemento a 2, podemos usar a
seguinte operação:

B - A = B + (-A)

B = 10011101 A = 01011110 (negativo em complemento a 2)

Primeiro, vamos obter o negativo de A em complemento a 2: Negativo de A = Inverter todos os bits de A e adicionar 1
Negativo de A = 10100001 + 1 = 10100010

Agora, realizamos a adição de B com o negativo de A: B + (-A) = 10011101 + 10100010 = 010111111

O resultado da subtração é 01011111 em complemento a 2, que em decimal é 95.

c) Para realizar a divisão do número A por dois, podemos realizar um deslocamento binário para a direita, mantendo o
bit de sinal. O processo é o seguinte:

A = 01011110

Deslocamento binário para a direita: A >> 1 = 00101111

O resultado da divisão de A por dois é 00101111 em complemento a 2, que em decimal é 47.

Repetindo o processo com o resultado da divisão anterior, temos:

00101111 >> 1 = 00010111 (complemento a 2) = 23 (decimal) 00010111 >> 1 = 00001011 (complemento a 2) = 11


(decimal) 00001011 >> 1 = 00000101 (complemento a 2) = 5 (decimal) 00000101 >> 1 = 00000010 (complemento a
2) = 2 (decimal) 00000010 >> 1 = 00000001 (complemento a 2) = 1 (decimal) 00000001 >> 1 = 00000000
(complemento a 2) = 0 (decimal)

Portanto, o processo de divisão de A por dois resulta em 47, 23, 11, 5, 2, 1 e 0.

d) O processo de divisão do número B por dois é semelhante ao processo de divisão de A por dois. Seguindo o mesmo
método, temos:

B = 10011101

Deslocamento binário para a direita: B >> 1 = 11001110

11001110 >> 1 = 11100111 (complemento a 2) = -25 (decimal) 11100111 >> 1 = 11110011 (complemento 1110011
>> 1 = 11111001 (complemento a 2) = -7 (decimal) 11111001 >> 1 = 11111100 (complemento a 2) = -4 (decimal)
11111100 >> 1 = 11111110 (complemento a 2) = -2 (decimal) 11111110 >> 1 = 11111111 (complemento a 2) = -1
(decimal) 11111111 >> 1 = 11111111 (complemento a 2) = -1 (decimal) 11111111 >> 1 = 11111111 (complemento a
2) = -1 (decimal)
Portanto, o processo de divisão de B por dois resulta em -25, -7, -4, -2, -1, -1 e -1.

5) Para converter o número em ponto flutuante representado na notação IEEE-754 para decimal, vamos seguir os
passos apropriados:

1. Determinar o sinal do número: O sinal é 0, o que significa que o número é positivo.


2. Converter a mantissa para decimal: A mantissa é 1100100 em binário. Na notação IEEE-754, a mantissa é
normalizada, o que significa que um bit "1" é implicitamente adicionado antes da vírgula. Portanto, a mantissa
é 1.1100100 em binário.
3. Converter o expoente para decimal: O expoente é -3 em decimal.
4. Calcular o valor em decimal: O valor do número em ponto flutuante é dado pela fórmula:

valor = (-1)^s * mantissa * 2^expoente

Substituindo os valores conhecidos:

valor = 1 * 1.1100100 * 2^(-3)

Calculando o resultado:

valor = 1.1100100 * 2^(-3) valor = 0.0011100100 em binário

Convertendo para decimal:

0.0011100100 = 0*(2^-1) + 0*(2^-2) + 1*(2^-3) + 1*(2^-4) + 1*(2^-5) + 0*(2^-6) + 0*(2^-7) + 1*(2^-8) + 0*(2^-9) +
0*(2^-10)

0.0011100100 = 0 + 0 + (1/8) + (1/16) + (1/32) + 0 + 0 + (1/256) + 0 + 0 0.0011100100 = 0.1640625

Portanto, o valor do número em ponto flutuante representado na notação IEEE-754 é aproximadamente 0.1640625 em
decimal.

Você também pode gostar