Sistemas de Computação
Mestr. Integr. Engª Informática, 1º ano
2015/2016
Docente responsável: A.J.Proença

Autoavaliação
Representação de informação

Última Modificação: 03 Mar 2016

 


Representação de informação


Resultados esperados em MIEI/SC: demonstrar que possui
 


A

R

B

E

Conhecimentos e competências específicas de Sistemas de Computação

       

- Identificar formas de representação binária de informação num computador (textual, numérica, audiovisual ou de comandos de um processador), e
- descrever como essa informação é efetivamente representada num computador

Ö
-
Ö
Ö
Ö
Ö
Ö
Ö

- Analisar ficheiros de documentos (c/ texto) e distinguir entre formatos proprietários de formatos baseados em texto anotado

- Ö Ö Ö

- Reconhecer os sistemas de numeração binário e hexadecimal e aplicar técnicas de conversão entre sistemas

Ö Ö Ö Ö

- Explicar a representação de números inteiros e reais (norma IEEE 754), visualizar a sua representação em binário, em ambiente laboratorial Unix/Linux & IA-32,
- ilustrar a representação de casos concretos através da resolução de problemas, e
- analisar as limitações de um sistema finito na representação de informação numérica

Ö
-
-
Ö
Ö
-
Ö
Ö
Ö
Ö
Ö
Ö

A1.
Resolva os seguintes problemas.

a) Mostrando os cálculos que efetuar, converta para hexadecimal o valor 0.26075*103

b) Um registo de 16 bits contém o conjunto de bits correspondente ao valor 0xD8. Mostre o valor que está lá guardado, em decimal, conforme o registo contém um valor inteiro sem sinal, ou o registo contém um valor inteiro (codificado em complemento para 2). Justifique os resultados apresentados.

c) Efetuando o menor nº possível de operações, represente na base 3 os seguintes valores: 11, 33, 99
Nota (para R): veja se consegue com apenas 2 divisões, explicitando o raciocínio seguido.

d) Uma variável em C declarada como unsigned short int (16 bits) é inicializada com um valor que corresponde à dimensão da memória cache no início dos processadores IA-32 com cache interna (i.e., 40K). Mostre, em hexadecimal, qual o valor que é guardado em memória.
Notas (para R): (i) tente resolver o problema sem efetuar qualquer divisão aritmética, mostrando os passos que seguir; e resolva adicionalmente o seguinte: (ii) repita o exercício para o dobro desse valor (80K), e (iii) repita o exercício mas considerando agora que a variável foi declarada como 
float, e efectuando o menor nº possível de operações..

Proposta de resolução
 

A2.
Um "cardeal" de LEI tentava explicar a um colega seu como é que estava organizada a página desta UC na Web.
Analise, com espírito crítico e usando os seus conhecimentos, a afirmação do "cardeal", conforme anotada no caderno do seu colega:
"A página web da UC SC é um ficheiro HTML com logotipos, textos formatados, datas e ...
Tudo isto está guardado num único ficheiro num PC:
- os textos são carateres alfanuméricos codificados em ASCII 7-bits;
- a formatação dos textos são comandos específicos que estão codificados em binário conforme o instruction set do Pentium;
- os logotipos são imagens JPEG;
- as datas, como são valores inteiros, estão codificados e guardadas no PC em complemento para 2"

Proposta de resolução
 

A3.
A gama de valores representáveis (na base decimal) num registo do Pentium está no intervalo:

a) [-2^31, +2^31[ , sempre que o registo contiver o valor de uma variável numérica que foi declarada num programa em C; comente esta afirmação.
Nota: a questão colocada nesta alínea tem uma subtileza para uma classificação R, ou mesmo B. Para uma classificação de apenas A, leia a sua reformulação na resolução (sugestão aos estudantes que pretendem mais que A: tentem encontrar essa "subtileza" antes de saltarem para a resolução).

b) [0, +2^32] se o registo for o IP/PC; comente esta afirmação.

c) [0, 9999] se o valor estiver representado como uma string de caracteres alfanuméricos em ASCII; comente esta afirmação.

d) [-2^128, +2^128] se for o conteúdo de um registo de vírgula flutuante de 32 bits; comente esta afirmação.
Nota: a resolução correta desta alínea apenas é exigida para a classificação R.

Proposta de resolução
 

R1.
Durante a execução do seguinte fragmento de código C, compilado para um processador compatível com IA-32, o espaço de memória atribuído às variáveis locais fval,ival,sval,tamp estende-se contiguamente, no sentido dos endereços crescentes, com início em 0xBFFFDA0 .
A sequência de valores
00 50 89 43 , expresso em formato hexadecimal, refere-se ao conteúdo dessas primeiras quatro células de memória.

    char tamp[3]="AJP"; // ‘A’ = 65 em decimal //
    short int sval;
    int ival;
    float fval;
    .....
    .....
    fval = ??? // valor especificado no enunciado //
    ival = (int) fval;
    sval = (short int) -fval; // notar o sinal menos //

a) Apresente o valor em decimal atribuído a cada uma das variáveis fval, ival, sval .

b) Considerando que o valor ASCII do caracter ´A´ é 65 (decimal), represente, em hexadecimal, no espaço de memória reservado, a variável tamp .

c) Represente, em hexadecimal, todas as variáveis declaradas, no fragmento de código, com a indicação precisa dos endereços ocupados na memória.

Proposta de resolução

Nota (para classificação B): se repetisse a resolução da alínea anterior para um computador big endian, que diferenças iria encontrar?

 

R2.
Numa aula de laboratório de SC, os grupos estavam a analisar o comportamento do processador na execução de um programa em C; mais concretamente, estavam a visualizar os conteúdos dos registos (em hexadecimal) após terem interrompido a execução a meio.
De repente, um grupo comenta: "Olha! Que coincidência! Os registos
%esp (stack pointer, i.e., o apontador para o topo da pilha em memória) e %eax (um outro que foi usado para representar uma das variáveis inteiras do programa) têm o mesmo valor, e portanto representam o mesmo valor decimal!"
E comenta um outro grupo: "E conosco também acontece o mesmo!!"
O docente vai ver ambos os terminais e confirma que os valores visualizados em cada monitor são o mesmo, embora sejam diferentes de um grupo para o outro. E comenta: "É verdade que esses 2 registos têm o mesmo conteúdo em binário! Mas um dos grupos fez uma afirmação correta, e o outro não!"

a) Encontre uma explicação válida para a posição do docente.
Nota: se esta questão não contivesse a alínea b), seria para uma classificação B.

b) Suponha que o 1º grupo via nos registos que tinham o mesmo conteúdo o valor 0x800c14, enquanto o segundo grupo tinha 0xfffffffe. Calcule e indique o valor, em decimal, armazenado em cada um dos registos, nos 2 grupos.

Proposta de resolução

 

B1.
Imagine que está a desenvolver software (em C) para controlo de um equipamento industrial (que requer bastante precisão numérica nas coordenadas). Esse software, depois de devidamente testado num PC, vai ser portado para um outro processador (um microcontrolador) que ficará embebido no equipamento. Contudo, esse processador não suporta o formato de precisão dupla conforme especificado na norma IEEE 754, pelo que todas as variáveis que tenham sido declaradas como double serão representadas apenas com 32 bits, no formato de precisão simples dessa mesma norma.
Considere os seguintes valores, resultados intermediários de operações com variáveis que declarou como sendo do tipo
double.
Mostre como serão representadas no processador
/memória do sistema embebido. Comente os resultados obtidos.

Nota: os valores apresentados nas alíneas seguintes estão em hexadecimal, e foram obtidos com ferramentas de debugging, enquanto o software era testado num Pentium.

a) 0x 48 A9 01 00 80 C5 00 00

b) 0x 34 09 01 00 80 00 00 00

c) 0x B7 41 90 10 80 00 C0 00

Proposta de resolução

 


 

Topo...

 

 

 

 


Resolução

Representação de informação

A1
Resolva os seguintes problemas.

a) Mostrando os cálculos que efetuar, converta para hexadecimal o valor 0.26075*103

Sugestão de resolução

Na conversão de um número em decimal para hexadecimal, é possível optar por uma de 2 alternativas (ambas correctas):
 - divisões/multiplicações sucessivas por 16 (método directo), ou
 - converter primeiro para binário (evitando, se possível, a realização de divisões/multiplicações por 2) e depois, sem operações, associar os bits em grupos de 4, para a esquerda/direita do ponto decimal, e atribuir a cada grupo de 4 bits o correspondente valor hexadecimal.

Este pb tem, contudo, uma mui ligeira complexidade adicional: o valor fornecido na base 10 é apresentado, não sob a forma de um nº contendo uma parte inteira e uma parte fraccionária (como se viu nas sessões teórico-práticas), mas sim com a chamada notação científica (uma parte fraccionária que multiplica por uma potência de 10).
Quando confrontados com uma questão deste tipo, certos estudantes ficam confusos e, por vezes, atacam logo com a resolução do pb sem pensar bem no assunto, i.e., assumem que este valor é constituído por 2 partes
 - a parte fraccionária 0.26075, e
 - o expoente 3,
convertem cada um desses números em separado para a nova base, e apresentam o resultado como sendo o produto da parte fraccionária (na nova base) pela nova base elevada ao expoente (convertido para a nova base). ISTO É UM DISPARATE!
Podem comprová-lo experimentando fazer uma conversão de um nº pequeno e simples - como por ex., o valor 5 escrito na forma 0.5*101 - e analisando criticamente o resultado dessa conversão:
  - pelo método disparatado daria 0.12*21; como a multiplicação de um nº pela sua base corresponde a deslocar o ponto decimal 1 casa para a direita, o resultado final desta multiplicação daria o valor 12. Acha que 5 no sistema decimal é igual a 1 no sistema binário?

Assim, antes de fazermos qq operação de conversão de bases, temos primeiro de passar este valor da notação científica para a outra notação; neste caso pegar no valor fornecido, fazer a multiplicação lá especificada pela potência da base 10, para se obter o valor 260.75. E é este o valor que irá ser convertido para hexadecimal.

Neste caso concreto (e na maioria dos casos) é mais simples passar primeiro para binário e depois para hexadecimal.

Se ainda não resolveu este pb, tente agora fazê-lo antes de espreitar pelo resto da resolução...

 

Vamos então à conversão, por partes:

 - parte inteira: 260 ; vamos evitar as divisões sucessivas, e tentar encontrar as potências de 2 que, somadas, perfazem esse valor; sabendo a tabuada de cor, recordamos que a potência de 2 mais próxima de 260 e <260 é 256 (=28); para 260 faltam 4, que é outra potência de 2 (=22); então 260 = 28 + 22 , ou seja, 260=1000001002 ;

 - parte fraccionária: 0.75 ; vamos evitar as multiplicações sucessivas, e tentar encontrar as potências negativas de 2 que, somadas, perfazem esse valor; este caso é demasiado simples: 0.75=0.5+0.25 = 1/2 + 1/22 , ou seja 0.75=0.112 ;

Temos então que 260.75 = 100000100.112 .
Para passar para hexadecimal é só agrupar em conjuntos de 4 bits, a contar do ponto decimal, para a esquerda e direita, acrescentando os zeros que forem precisos e que não alteram o valor: 0001 0000 0100.11002 .
Então, 260.75 = 0x104.C ou 104.C16 .

 

 

b) Um registo de 16 bits contém o conjunto de bits correspondente ao valor 0xD8. Mostre o valor que está lá guardado, em decimal, conforme o registo contém um valor inteiro sem sinal, ou o registo contém um valor inteiro (codificado em complemento para 2). Justifique os resultados apresentados.

Sugestão de resolução

O valor 0xD8 em binário é 1101 10002 .

Alguns pensarão que, como o bit mais à esquerda é 1, este valor em complemento para 2 representa um valor negativo. Será?

Pense e responda antes de continuar!

 

 

Atenção ao enunciado: esse valor está num registo de 16 bits; logo o que lá se encontra é o valor binário 0000 0000 1101 10002 .

E agora, para codificar em complemento para 2, o que se faz? Como é "complemento para 2", temos de trocar todos os bits e somar 1, verdade?

Pense e responda antes de continuar!

 

 

DISPARATE!!

Este valor em complemento para 2 representa um valor positivo, que vale em decimal tanto quanto um valor sem sinal!

Portanto, quer o registo contenha um valor inteiro sem sinal, ou um valor inteiro representado em complemento para 2, o valor em decimal é o mesmo e vem dado por 27+26+24+23 = 216 .

 

 

c) Efectuando o menor nº possível de operações, represente na base 3 os seguintes valores: 11, 33, 99
Nota (para R): veja se consegue com apenas 2 divisões, explicitando o raciocínio seguido.

Sugestão de resolução

Comecemos pelo 1º nº, o 11; na 1ª divisão pela nova base (3) daria quociente 3 e resto 2 (que será o 1º algarismo à esquerda do ponto decimal, no sistema de numeração de base 3); dividindo agora o quociente (3) novamente pela base (3) teríamos 0 de resto (o 2º algarismo à esq do ponto decimal) e 1 de quociente (o 3º e último algarismo).

Mas, será que precisávamos de fazer estas 2 divisões por 3? Neste caso tão simples, não dá para ver que 11 = 32+2, ou seja, 11 = 1*32+2*30 ?
Assim, neste caso, 11 = 1023 .

E agora 33: não será fácil de constatar que 33=11*3 , e que 99=11*9=11*32 ?

 

Se ainda não resolveu este pb, tente agora fazê-lo antes de espreitar pela resolução...
 

 

Ainda não conseguiu?
E não se lembra do que leu na resolução de a) ? Que a multiplicação de um nº pela sua base correspondia a deslocar o ponto decimal de uma casa para a direita? E no caso de um inteiro (sem ponto decimal, embora se possa subentendê-lo onde deveria estar), multiplicar pela sua base corresponde a deslocar todo o nº uma casa para a esquerda, acrescentando um zero à direita do nº.
Tente outra vez...


 

Resolução:

33 = 11*3 = (1*32+2*30)*31 = 1*33+2*31 = 10203

99 = 11*32 = (1*32+2*30)*32 = 1*34+2*32 = 102003   ou
99 = 33*3 = (1*33+2*31)*31 = 1*34+2*32 = 102003
 

 

d) Uma variável em C declarada como unsigned short int (16 bits) é inicializada com um valor que corresponde à dimensão da memória cache no início dos processadores IA-32 com cache interna (i.e., 40K). Mostre, em hexadecimal, qual o valor que é guardado em memória.
Notas (para R): (i) tente resolver o problema sem efetuar qualquer divisão aritmética, mostrando os passos que seguir; e resolva adicionalmente o seguinte: (ii) repita o exercício para o dobro desse valor (80K), e (iii) repita o exercício mas considerando agora que a variável foi declarada como 
float, e efetuando o menor nº possível de operações..

 

Sugestão de resolução:

Recorde a tabuada das potências de 2... O nº 40 não lhe diz nada?
Se não, então calcule 40*1024 e depois faça as sucessivas divisões por 2, aproveitando os restos das divisões.

Se prefere antes usar a cabeça, então...
40K = (32+8)*1K = (25+23)*210 = 215+213 = 1010 0000 0000 00002 = 0xA000 .

Para representar o dobro desse valor, isso corresponderia a multiplicar pela base (2), ou seja, deslocar o nº uma casa para a esquerda, acrescentando um zero à direita; mas, como em binário com 16 bits (sem sinal) o bit mais à esquerda neste caso é diferente de zero, se o deslocarmos um bit à esquerda vamos perdê-lo.
Esta variável, da maneira como foi declarada em C, não pode usar mais de 16 bits.
Logo, não é possível representar 80K com 16 bits, pois ultrapassa a capacidade máxima de representação de nºs com 16 bits (máx 216-1, ou seja, 64K-1).

Mas... se se pretende representá-lo em vírgula flutuante, então temos que preparar a expressão que nos calcula os 80K e adaptá-la à expressão que nos dá o valor em decimal de um nº em vírgula flutuante, precisão simples, no IEEE 754:
        V = (-1)S * 1.F * 2 E-127 =
        V = 2 * 40K = 2 * (32+8) * 1K = 2 * (25+23) * 210 = (25+23) * 211 = 10 10002 * 211 = 1.012 * 216 = (-1)0 * 1.012 * 2 E-127

Daqui se tira que:
S = 0
F = 010..02 (23 bits no total)
E = 127+16 = 143 = 27+23+22+21+20  = 1000 11112

Donde, em hexadecimal, o valor que será guardado em memória virá dado por (os bits do expoente estão sublinhados)
    0100 0111 1010 0000 0000 0000 0000 00002 = 0x47A00000

 

Regressar...

 


A2
Um "cardeal" de LEI tentava explicar a um colega seu como é que estava organizada a página desta disciplina na Web.
Analise, com espírito crítico e usando os seus conhecimentos, a afirmação do "cardeal", conforme anotada no caderno do seu colega:
"A página da UC SC é um ficheiro HTML com logotipos, textos formatados, datas e ...
Tudo isto está guardado num único ficheiro num PC:
- os textos são caracteres alfanuméricos codificados em ASCII 7-bits;
- a formatação dos textos são comandos específicos que estão codificados em binário conforme o instruction set do Pentium;
- os logotipos são imagens JPEG;
- as datas, como são valores inteiros, estão codificados e guardadas no PC em complemento para 2"

Sugestão de resolução

Vamos analisar o pb, relembrar alguns conceitos para compreender o enunciado, e refletir sobre a sua resolução; assim:

Julgo que com esta informação já não é preciso dizer mais nada. Falta apenas construir a resposta em Português simples e claro, eventualmente reutilizando algum deste texto..

 

Regressar...

 


A3
A gama de valores representáveis (na base decimal) num registo do Pentium está no intervalo:

a) [-2^31, +2^31[ , sempre que o registo contiver o valor de uma variável numérica que foi declarada num programa em C; comente esta afirmação.

Nota: a questão colocada nesta alínea tem uma subtileza para uma classificação R, ou mesmo B. Para uma classificação de apenas A, leia a sua reformulação na resolução (sugestão aos estudantes que pretendem mais que A: tentem encontrar essa "subtileza" antes de saltarem para a resolução).

Sugestão de resolução

Se não descobriu a "subtileza", eis a questão reformulada:

a) [-2^31, +2^31[ , sempre que o registo contiver o valor de uma variável numérica que foi declarada como int num programa em C; comente esta afirmação.

O Pentium é um processador característico da família IA-32; como tal, as variáveis do tipo int são representadas em complemento para 2, com 32 bits. A gama de valores inteiros (negativos e positivos) representáveis em binário, com n bits, é de 2n; em complemento para 2, há apenas uma representação do zero, sendo possível representar mais um valor inteiro negativo que positivo.
Assim, o intervalo de representação de valores será assimétrico, sendo possível representar 2n-1 valores negativos e apenas 2n-1-1 valores positivos, para além do zero.

Então, com 32 bits, a gama de valores representáveis no Pentium é [-2^31, +2^31[, conforme indicado no enunciado.

Voltando agora à questão original.
Na questão inicial não se especificava a maneira como a variável numérica tinha sido especificada: poderia ter sido como
int short int unsigned intunsigned short int, ou até como float ou double .
De todas estas formas de especificar, apenas  uma especificação do tipo
int poderia produzir o resultado indicado no enunciado; em todos os outros casos, o intervalo de valores seria distinto.

Sugestão adicional aos pretendentes de uma boa classificação: indique os intervalos para os 5 restantes tipos acima referidos. O resultado está no fim da alínea seguinte.
 

 

A gama de valores representáveis (na base decimal) num registo do Pentium está no intervalo:

a) (...)
b)
[0, +2^32] se o registo for o IP/PC; comente esta afirmação.

Sugestão de resolução

O registo Instruction Pointer (tradicionalmente conhecido como Program Counter) contém o apontador para a localização em memória da próxima instrução (em linguagem máquina) a ser executada pelo processador.
Sendo um endereço de memória, representa um valor inteiro sem sinal.
A gama de valores representáveis em binário, com n bits, é de
2n; vai de zero a 2n-1, inclusive.

Então, com 32 bits, a gama de endereços de memória representáveis em registo num Pentium é [0, +2^32[, e não o intervalo indicado no enunciado.
 

E agora a resolução à questão adicional colocada na sugestão de resolução da alínea anterior:
 - short
int[-2^15, +2^15[
 - unsigned int [-0, +2^32[
 - unsigned short int, [0, +2^16[
 - float, ]-2^128, +2^128[
 - double, ]-2^1024, +2^1024[ .


 

A gama de valores representáveis (na base decimal) num registo do Pentium está no intervalo:

a) (...)
b
) (...)
c) [0, 9999] se o valor estiver representado como uma string de caracteres alfanuméricos em ASCII; comente esta afirmação.

Sugestão de resolução

Se pretendemos representar um nº como uma string de caracteres alfanuméricos em ASCII, então cada algarismo será codificado como um carater ASCII, não necessitando de ocupar mais que uma célula de memória (8-bits).
Como cada registo do Pentium tem 32 bits, é possível escrever num registo todo o conteúdo de uma string de 4 elementos, i.e., é possível guardar num registo um nº codificado com 4 caracteres alfanuméricos, e como tal estando no intervalo '0000' a '9999'.

Assim, o intervalo de valores especificado no enunciado está de acordo com este raciocínio.
 

 

A gama de valores representáveis (na base decimal) num registo do Pentium está no intervalo:

a) (...)
b
) (...)
c) (...)

d)
[
-2^128, +2^128] se fôr o conteúdo de um registo de vírgula flutuante de 32 bits; comente esta afirmação.
Nota: a resolução correcta desta alínea apenas é exigida para a classificação R.

Sugestão de resolução

A representação de valores em vírgula flutuante no Pentium segue a norma IEEE 754; se se usarem apenas 32 bits, então segue a parte da norma referente à precisão simples.
A norma contempla a representação de valores normalizados, valores não-normalizados (os muito próximos de zero), e alguns casos especiais (incluindo o zero e os infinitamente grandes, quer positivos quer negativos).
Como se pretende a gama de valores representáveis, desde o muito grande negativo, até ao muito grande positivo, esta gama é integralmente definida apenas pelos valores normalizados. E o valor decimal de um nº representado em binário normalizado, segundo o IEEE 754 vem dado por
        V = (-1)S * 1.F * 2 E-127

Então pretende-se o maior valor de F e de E para os valores de S=0 e S=1; isto corresponde a F=1..12 (23 bits) e E=1111 11102 (para ser normalizado tem de ser diferente de tudo uns), i.e., E=254.

A gama de valores encontra-se então entre -1.111111111111111111111112*2127  e +1.111111111111111111111112*2127 , incluindo estes 2 valores extremos.
Os valores logo a seguir a estes, mas já fora do intervalo de valores representáveis, seriam -2*2
127 e +2*2127 , o que corresponde a representarmos a gama de valores como estando no intervalo ]-2^128, +2^128
[, e não no intervalo indicado no enunciado.
 

Regressar...

 



R1
Durante a execução do seguinte fragmento de código C, compilado para um processador compatível com IA-32, o espaço de memória atribuído às variáveis locais fval,ival,sval,tamp estende-se contiguamente, no sentido dos endereços crescentes, com início em 0xBFFFDA0 .
A sequência de valores
00 50 89 43 , expresso em formato hexadecimal, refere-se ao conteúdo dessas primeiras quatro células de memória.

    char tamp[3]="AJP"; // ‘A’ = 65 em decimal //
    short int sval;
    int ival;
    float fval;
    .....
    .....
    fval = ??? // valor especificado no enunciado //
    ival = (int) fval;
    sval = (short int) -fval; // notar o sinal menos //

a) Apresente o valor em decimal atribuído a cada uma das variáveis fval, ival, sval .

Sugestão de resolução

De acordo com o enunciado, a variável fval é uma variável declarada como sendo de vírgula flutuante, de precisão simples (32 bits, norma IEEE 754, como acontece em computadores compatíveis com o IA-32); e essa variável está em memória, ocupando as 4 células (32 bits = 4*8) que se seguem a 0xBFFFDA0 . O conteúdo dessas 4 células é tb indicado no enunciado: "00 50 89 43 , expresso em formato hexadecimal"; se nos lembrarmos que o IA-32 é little endian, sabemos que na 1ª célula se encontra o byte menos significativo, e na última estará o mais significativo.

Então, o conteúdo da variável fval  representado em hexadecimal e binário, de acordo com a norma IEEE, é, respectivamente (os bits do expoente estão sublinhados)
    0x43895000    e    0100 0011 1000 1001 0101 0000 0000 000
02

S = 0 (valor positivo)
E = 1000 0111
2 => normalizado, logo em notação excesso 127 ; subtraindo 127 para se saber quanto vale o expoente: subtrai-se 128 (remove-se o 1 à esquerda) e soma-se 1; dá 10002 = 8
F = 0.0001 0010 1012

Sabendo que o valor em decimal de um nº em vírgula flutuante, normalizado, precisão simples, representado pela norma IEEE 754, é calculado pela expressão
    V = (-1)S * 1.F * 2 E-127
então
   
fval = (-1)0 * 1.0001 0010 1012 * 2 8 = 1 0001 0010.1012 = 256+16+2+1/2+1/8 = 274.625

De acordo com o fragmento de código C disponibilizado, ival  é o resultado da conversão de um valor em vírgula flutuante (fval) para um valor inteiro (codificado em complemento para 2), através da truncatura da parte decimal; neste caso concreto,
   
ival = (int) 274.625 = 274

Também de acordo com o fragmento de código C disponibilizado, sval  é o resultado da conversão de um valor em vírgula flutuante (-fval) para um valor inteiro (codificado em complemento para 2), "curto" (16 bits), através da truncatura da parte decimal; neste caso concreto,
   
sval = (short int
) -274.625 = -274

 

Durante a execução do sequinte fragmento de código C, compilado para um processador compatível com IA-32, o espaço de memória atribuído às variáveis locais fval,ival,sval,tamp estende-se contiguamente, no sentido dos endereços crescentes, com início em 0xBFFFDA0 .
A sequência de valores
00 50 89 43 , expresso em formato hexadecimal, refere-se ao conteúdo dessas primeiras quatro células de memória.

    char tamp[3]="AJP"; // ‘A’ = 65 em decimal //
    short int sval;
    int ival;
    float fval;
    .....
    .....
    fval = ??? // valor especificado no enunciado //
    ival = (int) fval;
    sval = (short int) -fval; // notar o sinal menos //

a) (...)
b) Considerando que o valor ASCII do caracter ´A´ é 65 (decimal), represente, em hexadecimal, no espaço de memória reservado, a variável
tamp .

Sugestão de resolução

A tabela ASCII codifica as letras do alfabeto com códigos adjacentes e crescendo com a ordem alfabética; assim, se 'A' é codificado por 65, 'J' deverá ser codificado por 74, e 'P' por 80.
Por outro lado, numa string (que é representada normalmente por um vector de caracteres), o conjunto de caracteres que lhe são assim atribuídos são colocados nos primeiros elementos do vector, e se esses não encherem a totalidade do vector, então são atribuídos caracteres null (ASCII '0', ou como normalmente se designa em C, '\0') aos restantes elementos do vector (string).
Assim, o vector
tamp[3], que tem reservado na memória espaço para 4 elementos de 1 byte, contém os seguintes valores em hexadecimal (resultantes da codificação directa dos valores em decimal acima referidos, 65, 74, 80 e 0): 41 4A 50 00.

 

 

Durante a execução do sequinte fragmento de código C, compilado para um processador compatível com IA-32, o espaço de memória atribuído às variáveis locais fval,ival,sval,tamp estende-se contiguamente, no sentido dos endereços crescentes, com início em 0xBFFFDA0 .
A sequência de valores
00 50 89 43 , expresso em formato hexadecimal, refere-se ao conteúdo dessas primeiras quatro células de memória.

    char tamp[3]="AJP"; // ‘A’ = 65 em decimal //
    short int sval;
    int ival;
    float fval;
    .....
    .....
    fval = ??? // valor especificado no enunciado //
    ival = (int) fval;
    sval = (short int) -fval; // notar o sinal menos //

a) (...)
b) (...)

c) Represente, em hexadecimal, todas as variáveis declaradas, no fragmento de código, com a indicação precisa dos endereços ocupados na memória.

Sugestão de resolução

São 4 as variáveis declaradas neste fragmento de código C: fval,ival,sval,tamp.
O valor em decimal das primeiras 3 variáveis foi calculado em a); falta agora recuperar/calcular os seus valores em hexadecimal:
 -
fval está no texto do enunciado;
 -
ival é a representação em binário/hexadecimal, complemento para 2, de '274': 0000 0000 0000 0000 0000 0001 0001 00102 <=> 0x112
 -
sval é a representação em binário/hexadecimal, complemento para 2, com 16 bits,  de '-274': 1111 1110 1110 11102 <=> 0xFEEE
O valor em hexadecimal da 4ª variável foi calculado na alínea anterior.

Localização das variáveis: fval (ocupando 4 células) em 0xBFFFDA0 ; ival (4 células) em  0xBFFFDA4 ; sval (2 células) em 0xBFFFDA8 ; tamp (4 células) em 0xBFFFDAA .

Resumindo, sem esquecer que o IA-32 é little endian:
0x 0B FF FD A0 : 00

       "    A1 : 50
       "    A2
: 89
       "    A3
: 43
0x 0B FF FD A4 :
12
       "    A5
: 0
1
       "    A6
: 00
       "    A7
: 00
0x 0B FF FD A8 :
EE
       "    A9
:
FE
0x 0B FF FD AA :
41
       "    AB
:
4A
       "    AC
:
50
       "    AD
:
00


E se estivéssemos a analisar um computador big endian, em vez de um baseado no Pentium?

A diferença está apenas na maneira como uma quantidade escalar, não estruturada - e cuja dimensão em nº de bits é superior à de uma célula de memória - é armazenada nessas células. E o pb do big versus little endian apenas se coloca neste caso.
No nosso exercício, temos 3 variáveis escalares e uma estruturada (uma string, representada como um array), cujos elementos são carateres (e portanto requerendo cada apenas 8 bits, a dimensão de uma célula). Apenas as variáveis escalares irão ser afetadas por esta questão.
Então, aqueles 14 bytes ficariam assim armazenados em memória, a partir do endereço inicial
   
0x 0B FF FD
A0 : 43 89 50 00 00 00 01 12 FE EE 41 4A 50 00
 

Regressar...

 



R2
Numa aula de laboratório de SC, os grupos estavam a analisar o comportamento do processador na execução de um programa em C; mais concretamente, estavam a visualizar os conteúdos dos registos (em hexadecimal) após terem interrompido a execução a meio.
De repente, um grupo comenta: "Olha! Que coincidência! Os registos %esp (stack pointer) e %eax (um outro que foi usado para representar uma das variáveis inteiras do programa) têm o mesmo valor, e portanto representam o mesmo valor decimal!"
E comenta um outro grupo: "E connosco também acontece o mesmo!!"
O docente vai ver ambos os terminais e confirma que os valores visualizados em cada monitor são o mesmo, embora sejam diferentes de um grupo para o outro. E comenta: "É verdade que esses 2 registos têm o mesmo conteúdo em binário! Mas um dos grupos fez uma afirmação correcta, e o outro não!"

a) Encontre uma explicação válida para a posição do docente.
Nota: se esta questão não contivesse a alínea b), seria para uma classificação B

Sugestão de resolução

Vamos analisar cuidadosamente a afirmação do docente: (i) ele confirma a veracidade dos dados visualizados no monitor, i.e., que os registos %esp e %eax têm a mesma representação em hexadecimal/binário, em cada um dos grupos que fez a afirmação (i.e., a 1ª parte da afirmação deles está correcta: "têm o mesmo valor" ); mas (ii) ele contesta a afirmação de um dos grupos, e só poderá estar a referir-se à 2ª parte da afirmação: "e portanto representam o mesmo valor decimal!"

A questão resume-se a: em que situações é que a mesma codificação de 2 números (em binário/hexadecimal) pode não representar o mesmo valor no sistema de numeração decimal?

Pense um pouco antes de continuar!

 

 

Resposta: se esses números representarem tipos de dados inteiros distintos, e algo mais...
Neste caso em particular, sabe-se que um dos valores é um inteiro sem sinal (mais concretamente, um endereço de memória, que é o valor do apontador para a stack); se o outro registo
"foi usado para representar uma das variáveis inteiras do programa", é muito provável que essa variável tenha sido declarada como int, logo um inteiro com sinal.
Então, a 2ª questão que se pode colocar é a seguinte: em que situação é que a representação binária de um inteiro sem sinal é diferente da de um inteiro em complemento para 2? Apenas na representação de nºs negativos em complemento para 2! Se o nº for positivo e puder ser representado na notação em complemento para 2, então essa representação é igual à conversão directa de um nº decimal (sem sinal) num nº binário/hexadecimal.
Completando a resposta começada em cima: se esses números representarem tipos de dados inteiros distintos, e se não forem ambos positivos.

 


b) Suponha que o 1º grupo via nos registos que tinham o mesmo conteúdo o valor 0x800c14, enquanto o segundo grupo tinha 0xfffffffe. Calcule e indique o valor, em decimal, armazenado em cada um dos registos, nos 2 grupos.

Sugestão de resolução

1º grupo

Passando 0x800c14 para binário com 32 bits: 0000 0000 1000 0000 0000 1100 0001 01002 ; representa um valor positivo (a variável inteira em %eax) ou um valor sem sinal (o apontador para o topo da stack), e ambos valem o mesmo:
    223 + 211 + 210 + 24 + 22

2º grupo

Passando 0xfffffffe para binário com 32 bits: 1111 1111 1111 1111 1111 1111 1111 11102 ; representa um valor negativo pequeno (o que estará em  %eax), ou um valor muito grande se for considerado sem sinal (o apontador para o topo da stack), e valem:
 - em
%eax : calculando o complemento para 2, este conjunto de bits vale (-102) ou (
-2) em decimal;
 - em
%esp: o seu conteúdo é um endereço de memória que vale (232 + 231 + ... + 23 + 22 + 21) ou, mais simplesmente, (232
-2).

 

Regressar...

 



B1
Imagine que está a desenvolver software (em C) para controlo de um equipamento industrial (que requer bastante precisão numérica nas coordenadas). Esse software, depois de devidamente testado num PC, vai ser portado para um outro processador (um microcontrolador) que ficará embebido no equipamento. Contudo, esse processador não suporta o formato de precisão dupla conforme especificado na norma IEEE 754, pelo que todas as variáveis que tenham sido declaradas como double serão representadas apenas com 32 bits, no formato de precisão simples dessa mesma norma.
Considere os seguintes valores, resultados intermediários de operações com variáveis que declarou como sendo do tipo
double.
Mostre como serão representadas no processador/memória do sistema embebido. Comente os resultados obtidos.

Nota: os valores apresentados nas alíneas seguintes estão em hexadecimal, e foram obtidos com ferramentas de debugging, enquanto o software era testado num Pentium.

a) 0x 48 A9 01 00 80 C5 00 00

Sugestão de resolução

Há uma decisão de fundo a tomar antes de atacar este pb:
(i) vamos 1º identificar os limites de representação de nºs normalizados e desnormalizados (intervalo de valores e resolução) para cada um dos formatos (precisão simples/dupla) e depois analisar cada um dos valores propostos, ou
(ii) começamos de imediato a tentar calcular o valor decimal de cada um destes dados e tentamos convertê-los depois para o novo formato.

A 1ª abordagem dá-nos uma melhor perspetiva do que está em causa, mas exige mais trabalho no início; contudo, como esta questão tem 3 conjuntos de valores, este acréscimo de trabalho inicial é depois "amortizado" em cada uma das alíneas consequentes. Vamos pois seguir esta abordagem.

Um outro aspeto a analisar é tentar identificar, antes de qq outra atividade, que tipo de pb's poderão surgir quando tentamos converter um valor de um formato em FP para outro que utiliza menos bits, pois coloca-nos em melhor posição para uma análise crítica dos resultados que formos obtendo ao longo da resolução. Vamos ver o quero dizer com isto.

O que distingue estes 2 formatos é essencialmente o nº de bits usado para representar o expoente (8 e 11) e a mantissa (23 e 52).
Implicações:
 - expoente: quanto maior o nº de bits usado no expoente maior é a gama de valores que é possível representar, quer no eixo positivo, quer no negativo; isto terá como consequência que (i) valores muito grandes (em modo absoluto) em precisão dupla poderão não ter representação em precisão simples (overflow positivo ou negativo, que de acordo com a norma IEEE será codificado como sendo ±
¥ ), ou (ii) valores normalizados relativamente pequenos (em modo absoluto) em precisão dupla poderão ter de ser representados como desnormalizados em precisão simples, ou ainda que (iii) valores normalizados muito pequenos (em modo absoluto) em precisão dupla poderão não ter representação em precisão simples (underflow positivo ou negativo, que de acordo com a norma IEEE será codificado como sendo ± 0 ); se esta última situação ocorrer, então certamente todos os valores desnormalizados em precisão dupla serão considerados underflow  (positivo ou negativo) e representados como ± 0, de acordo com a norma IEEE;
 - mantissa:
quanto maior o nº de bits usado na mantissa maior é a resolução do valor representado i.e., a sua representação possui um maior nº de dígitos significativos; na conversão de um valor noutro com menos bits para representar a mantissa, os dígitos em excesso são removidos (por arredondamento e não por  truncatura) e o resultado da conversão pode ser um valor diferente do original, nomeadamente se forem removidos dígitos significativos diferentes de zero; isto é ainda mais crítico se o resultado da conversão for um valor desnormalizado, uma vez que este tem um nº variável de dígitos significativos (diminui consoante o valor se aproxima de zero). Questão para um candidato a Excelente: quantos dígitos decimais significativos estão num valor em FP (formato normalizado) em precisão simples e em dupla?

Vamos então identificar os limites de representação de nºs normalizados e desnormalizados:
 - precisão simples, caminhando de –
¥ até + ¥ (em caso de dúvida, consultar a resolução da alínea d) de A3)
   
]-2^128, -2^-126] ]-2^-126, -2^-149] [2^-149, 2^-126[ [2^-126, 2^128[
 -  - precisão dupla, caminhando de –
¥ até + ¥ (à semelhança da precisão simples, o expoente usa a notação excesso 2n-1-1, i.e., 1023)
   
]-2^1024, -2^-1022] ]-2^-1022, -2^-1074] [2^-1074, 2^-1022[ [2^-1022, 2^1024[

Olhando para estes intervalos, já são mais claras a afirmações feitas anteriormente sobre as implicações do nº diferente de bits para representar o expoente; apenas alguns exemplos:
 - qq nº em precisão dupla normalizado 
³2128 <21024 é overflow positivo quando convertido para precisão simples;
 - qq nº em precisão dupla normalizado 
³2-149 <2-126 é representado como desnormalizado quando convertido para precisão simples;
 - qq nº em precisão dupla normalizado 
³2-1074 <2-149 é underflow positivo quando convertido para precisão simples;
 - qq nº em precisão dupla desnormalizado é underflow (positivo ou negativo) quando convertido para precisão simples.

E agora vamos ver o caso concreto desta alínea (os bits do expoente estão sublinhados):
   
0x 48 A9 01 00 80 C5 00 00 = 0100 1000 1010 1001 0000 0001 0000 0000 1000 0000 1100 0101 0000 0000 0000 00002

S = 0 (positivo)
E = 100 1000 10102 (=> normalizado)
= 1024+128+8+2 = (1024+138)
F =
1001 0000 0001 0000 0000 1000 0000 1100 0101 0000 0000 0000 00002

Donde,
V
= (-1)S * 1.F * 2 E–1023 =  = (-1)0 * 1.F * 2 (1024+138) –1023 = 1.F * 2139  => 
=> não é possível representá-lo em precisão simples por estar fora da gama de valores representáveis (overflow positivo); vai ter de ser codificado como sendo +
¥

Resultado:
0111 1111 1000 0000 0000 0000 0000 0000
2 = 0x 7F 80 00 00
 

 

Imagine que está a desenvolver software (em C) para controlo de um equipamento industrial (que requer bastente precisão numérica nas coordenadas). Esse software, depois de devidamente testado num PC, vai ser portado para um outro processador (um microcontrolador) que ficará embebido no equipamento. Contudo, esse processador não suporta o formato de precisão dupla conforme especificado na norma IEEE 754, pelo que todas as variáveis que tenham sido declaradas como double serão representadas apenas com 32 bits, no formato de precisão simples dessa mesma norma.
Considere os seguintes valores, resultados intermediários de operações com variáveis que declarou como sendo do tipo
double.
Mostre como serão representadas no processador do sistema embebido. Comente os resultados obtidos.

Nota: os valores apresentados nas alíneas seguintes estão em hexadecimal, e foram obtidos com ferramentas de debugging, enquanto o software era testado num Pentium.

a) (...)
b) 0x 34 09 01 00 80 00 00 00

Sugestão de resolução

Após todos os considerandos da alínea anterior
   
0x 34 09 01 00 80 00 00 00 = 0011 0100 0000 1001 0000 0001 0000 0000 1000 0000 0000 0000 0000 0000 0000 00002

S = 0 (positivo)
E = 011 0100 00002 (=> normalizado) = 512+256+64 = 832
F =
1001 0000 0001 0000 0000 1000 0000 0000 0000 0000 0000 0000 00002

Donde,
V = (-1)S * 1.F * 2 E–1023 =  = (-1)0 * 1.F * 2 832–1023 = 1.F * 2–191  =>
=> não é possível representá-lo em precisão simples por estar fora da gama de valores representáveis (underflow positivo); vai ter de ser codificado como sendo +0

Resultado:
0000 0000 0000 0000 0000 0000 0000 0000
2 = 0x0

 

 

Imagine que está a desenvolver software (em C) para controlo de um equipamento industrial (que requer bastente precisão numérica nas coordenadas). Esse software, depois de devidamente testado num PC, vai ser portado para um outro processador (um microcontrolador) que ficará embebido no equipamento. Contudo, esse processador não suporta o formato de precisão dupla conforme especificado na norma IEEE 754, pelo que todas as variáveis que tenham sido declaradas como double serão representadas apenas com 32 bits, no formato de precisão simples dessa mesma norma.
Considere os seguintes valores, resultados intermediários de operações com variáveis que declarou como sendo do tipo
double.
Mostre como serão representadas no processador do sistema embebido. Comente os resultados obtidos.

Nota: os valores apresentados nas alíneas seguintes estão em hexadecimal, e foram obtidos com ferramentas de debugging, enquanto o software era testado num Pentium.

a) (...)
b)
(...)
c) 0x B7 41 90 10 80 00 C0 00

Sugestão de resolução

Após todos os considerandos da alínea a)
   
0x B7 41 90 10 80 00 C0 00 = 1011 0111 0100 0001 1001 0000 0001 0000 1000 0000 0000 0000 0000 1100 0000 00002

S = 1 (negativo)
E = 011 0111 01002 (=> normalizado) = 512+256+64+32+16+4 = 884
F =
0001 1001 0000 0001 0000 1000 0000 0000 0000 0000 1100 0000 00002

Donde,
V = (-1)S * 1.F * 2 E–1023 =  = (-1)1 * 1.F * 2 884–1023 = 1.0001 1001 0000 0001 0000 1000 0000 0000 0000 0000 112 * 2–139  =>
=> representável em precisão simples, mas como valor desnormalizado.

Então, vai ser preciso modificar a expressão acima apresentada, para que ela fique semelhante à expressão que nos dá o valor de um nº desnormalizado em precisão simples:
V =
(-1)S * 0.F * 2 –126 = –1.0001 1001 0000 0001 0000 1000 0000 0000 0000 0000 112 * 2–139  =
= –0.0000 0000 0000 1000 1100 1000 0010 0001 0000 0000 0000 0001 12 * 213 * 2–139  =
(como só existem 23 bits na mantissa em precisão simples, vão-se perder dígitos significativos
¹ 0 na conversão...)
= –
0.0000 0000 0000 1000 1100 1002 * 2–126

Resultado:
1000 0000 0000 0000 0000 0100 0110 0100
2 = 0x 80 00 04 64 (com perda de dígitos significativos)

 

Regressar...

Topo...

 

 


Página mantida por aproenca<at>di.uminho.pt
Última Modificação: 03 Mar 2016