# A doubt of hexadecimal and c

3

The exercise that is proposed to do in C is as follows:

More or less the approach is clear to me the table represents the values of tab [] in hexadecimal and on the right its expression in ASCII, as it tells us to do it according to the example and since 1Byte is 2 hexadecimal characters I must assume that each element of the array must occupy 4Bytes (I do not know if this is by agreement or some other reason, as I understand int occupies 2Bytes in C, so I suppose it would be because the one who poses the problem wants to do it), well my The question is as follows: As I see to represent the elements of tab [] only two hexadecimal characters are used, that is, (N1) * 16 ^ 1 + (N2) * 16 ^ 0, so the maximum I can write is 0xff = 255, if in the array I write a number greater than 255 what is the way to represent it here? well I guess the other 3Bytes are for something not?

asked by latiagertrutis 22.07.2017 в 03:20
source

2

the int type was defined as a word in the micro architectures 8086, 80286, however from the 80386, int is by default a double word

Basically what they ask you is to print lines of `16B` in 2 columns, the first column is the hexadecimal representation in groups of `2B` while the second column is the representation in ascii.

The pseucode would be the following

``````void
print_memory (const void *addr, size_t size)
{
{
imprimir byte en hex
if(se ha imprimido 2B)
{
imprimir espacio
}

if(se han imprimido 16B)
{
imprimir los 16B anteriores en ascii
imprimir salto de linea
}

}
imprimir en forma alineada los ascii de la línea incompleta
imprimir salto de linea
}
``````

Implementation is trivial

print_memory.c

``````#include <ctype.h> // isprint
#include <stdio.h>  // printf
#include <stdlib.h> // size_t

#define LINE_IN_BYTES         0x10
#define WORD_IN_BYTES         2
#define HEX_DIGIT_PER_CHAR    2

#define IS_ODD(x) (x % 2 == 1)

void print_memory (const void*, size_t);
static        void print_ascii (const void*, size_t);
static inline void print_spaces (size_t);

int
main (void)
{
int tab[10] = {0, 23, 150, 255, 12, 16, 21, 42};
char m[17] = "Hola mundo";

print_memory (tab, sizeof(tab));
print_memory (m, sizeof(m));

return 0;
}

void
print_memory (const void *addr, size_t size)
{
size_t i;
size_t resto;
const unsigned char *c;

return;

for (i = 1; i <= size; i++)
{
c = (addr + i - 1);
printf ("%02hhx", *c);

if (i % WORD_IN_BYTES == 0)
{
putchar (' ');
}

if (i % LINE_IN_BYTES == 0)
{
print_ascii (c - LINE_IN_BYTES + 1, LINE_IN_BYTES);
printf ("\n");
}
}

if ((resto = size % LINE_IN_BYTES) > 0) // falta ascii que imprimir
{
print_spaces ((HEX_DIGIT_PER_CHAR + 0.5) * (LINE_IN_BYTES - resto)); // rellena lo faltante
if(IS_ODD (resto))
putchar (' '); // alinea a palabra
print_ascii (c - resto + 1, resto);
printf ("\n");
}
}

static void
print_ascii (const void *addr, size_t size)
{
size_t i;
const unsigned char *c;

for (i = 0; i < size; i++)
{
if (isprint (*c))
putchar (*c);
else
putchar ('.');
}
}

static inline
void
print_spaces (size_t size)
{
size_t i;
for (i = 0; i < size; i++)
{
putchar(' ');
}
}
``````

Compile it

``````\$ gcc print_memory.c -o print_memory -Wall -Werror; ./print_memory | cat -e
0000 0000 1700 0000 9600 0000 ff00 0000 ................\$
0c00 0000 1000 0000 1500 0000 2a00 0000 ............*...\$
0000 0000 0000 0000                     ........\$
486f 6c61 206d 756e 646f 0000 0000 0000 Hola mundo......\$
00                                      .\$
``````

Observations: Do not worry about the endianness , since it does not vary much, since ANSI C specifies that the elements in an array should be stored as they are declared, the first element of the array being the least address in memory.

``````               MAYOR

0         4
===========
0      tab + 36
-----------
0      tab + 32
-----------
42      tab + 28
-----------
21      tab + 24
-----------
16      tab + 20
-----------
12      tab + 16
-----------
255      tab + 12
-----------
150      tab +  8
-----------
23      tab +  4
-----------
0      tab +  0
===========
MENOR
``````

Whatever the endianness , the previous figure does not change.

# Little endian

The previous figure for little endian would be the following

``````               MAYOR

0         4
===========
0x0000 0000      tab + 36
-----------
0x0000 0000      tab + 32
-----------
0x2A00 0000      tab + 28
-----------
0x1500 0000      tab + 24
-----------
0x1000 0000      tab + 20
-----------
0x0C00 0000      tab + 16
-----------
0xFF00 0000      tab + 12
-----------
0x9600 0000      tab +  8
-----------
0x1700 0000      tab +  4
-----------
0x0000 0000      tab +  0
===========
MENOR
``````

# Big endian

``````               MAYOR

0         4
===========
0x0000 0000      tab + 36
-----------
0x0000 0000      tab + 32
-----------
0x0000 002A     tab + 28
-----------
0x0000 0015      tab + 24
-----------
0x0000 0010      tab + 20
-----------
0x0000 000C      tab + 16
-----------
0x0000 00FF      tab + 12
-----------
0x0000 0096      tab +  8
-----------
0x0000 0017      tab +  4
-----------
0x0000 0000      tab +  0
===========
MENOR
``````

source
1

I do not know if this is by agreement or some other reason, as I have   understood int occupies 2Bytes in C.

What returns `sizeof(int)` depends on the compiler, but currently it is much more common than `int` have a size of 4 bytes, this would be 8 hexadecimal digits.

If in the array I write a number greater than 255 which is the form of   represent it here?

If you look at what the function returns `print_memory` you will realize that each element of `tab` corresponds to 8 digits in hexadecimal, that is, 0 will be printed as `0000 0000` , 255 will be printed as `ff00 0000` , what happens if we go from 255 ?, then nothing, for example 256 would be printed as `1000 0000` , to explain why this would happen more clearly realize this program that does almost the same as the one that shows in the statement .

``````#include <stdio.h>
#include <stdlib.h>

void print_memory(int *array, size_t size) {
int i, times = size / sizeof(int);

for (i = 0; i < times; i++) {
printf("%08x ", array[i]);

if ((i + 1) % 4 == 0)
printf("\n");
}
}

int main() {
int tab[10] = {256, 23, 150, 255, 12, 16, 21, 42};

print_memory(tab, sizeof(tab));

return 0;
}
``````

If we execute it, we will obtain:

``````00000100 00000017 00000096 000000ff
0000000c 00000010 00000015 0000002a
00000000 00000000
``````

As you see, 255 is represented by `000000ff` , but in the original program it is printed in Little Endian , so so there is `ff000000` , that is, 256 which would be represented by `00000100` in the original program would be shown as `10000000` , the problem of this is that confusion originates, since you could not know if `10000000` represents 256, 1 or 12 (if you look at your sentence 12 it is also printed as `10000000` )

In summary

The program of the statement does the same as the one I put above, but it prints the hexadecimal numbers in little endian format, and for the part of the characters it will only be necessary to print what these numbers represent in ASCII code.