Suppose we've got two integer and character variables:

int adad=12345;
char character;

Assuming we're discussing a platform in which, length of an integer variable is longer than or equal to three bytes, I want to access third byte of this integer and put it in the character variable, with that said I'd write it like this:

character=*((char *)(&adad)+2);

Considering that line of code and the fact that I'm not a compiler or assembly expert, I know a little about addressing modes in assembly and I'm wondering the address of the third byte(or I guess it's better to say offset of the third byte) here would be within the instructions generated by that line of code themselves, or it'd be in a separate variable whose address (or offset) is within those instructions ?

hi,

decimal 12345 is hex 0x00003039. So to get a more practical example I changed:

character=*((char *)(&adad)+2);  // 0x00 is stored

to:

character=*((char *)(&adad)+1);  // 0x30 is stored

Assuming Intel processor, the assembly should look like:

lea ebx, adad         ; address points to 0x39 (little Endian)
add ebx, 1            ; address of 2nd byte, points to 0x30
mov al, [ebx]         ; loads 0x30 into reg al
mov character, al     ; stores 0x30 into character

After execution above code:

printf ("character: %x\n", character);

should output character: 30

I hope this is a little help.

Addition: Instead of add ebx,1 and mov al, [ebx] also displacement addressing: mov al, [ebx+1] is possible.

-- tesu

Edited 6 Years Ago by tesuji: n/a

I would think that most modern compilers generate flat 32-bit code, don't they?. An int occupies 32 bits of memory. To see that, declare an int array, for example int a[3] and watch &a, &a[1] and &a[2] during debugging.

Here is the disassembly of the code generated by the visual studio compiler for your snippets above:

int main()
{
01171350  push        ebp  
01171351  mov         ebp,esp  
01171353  sub         esp,0D8h  
01171359  push        ebx  
0117135A  push        esi  
0117135B  push        edi  
0117135C  lea         edi,[ebp-0D8h]  
01171362  mov         ecx,36h  
01171367  mov         eax,0CCCCCCCCh  
0117136C  rep stos    dword ptr es:[edi]  
    int adad=12345;
0117136E  mov         dword ptr [adad],3039h  
    char character;
    character=*((char *)(&adad)+2);
01171375  mov         al,byte ptr [ebp-6]  
01171378  mov         byte ptr [character],al  

    return 0;

This is probably not of much help.
As 12345 = 3039h, its first (most significant) two bytes are zero, so that character = 0. With adad = 1234567 = 12d687h, you get character = 18 = 12h, as expected.

Edited 3 Years Ago by Reverend Jim: Fixed formatting

This article has been dead for over six months. Start a new discussion instead.