UMBC CMSC 313 -- Fixing The Size Of Structures Previous | Next


Fixing The Size Of Structures

C

To get the size of the C structure to match the size of the assembly language version, there is a compiler directive that was suppress the alignment, pack. There will be no extra bytes added to the stucture at all. The syntax is a bit unexpected, but what you are using is actually a macro!

Revised Code

#include 
#include 

struct foo
{
    short  a;          /* 2 bytes */
    int    b;          /* 4 bytes */
    char   c;          /* 1 byte  */
    int    d;          /* 4 bytes */
    char   e[ 6 ];     /* 6 bytes */
                       /* Total:  17 bytes, do the math */
} __attribute__((packed));  /* Force the compiler to use the minimum 
                               amount of memory for the structure */

int main ( void )
{

    struct foo s, t;
    int        num;

    printf( "size of s = %d\n", sizeof( s ) );
    printf( "address of s = %x\n", (unsigned int)&s );
    printf( "    address of s.a = %x\n", (unsigned int)&s.a );
    printf( "    address of s.b = %x\n", (unsigned int)&s.b );
    printf( "    address of s.c = %x\n", (unsigned int)&s.c );
    printf( "    address of s.d = %x\n", (unsigned int)&s.d );
    printf( "    address of s.e = %x\n", (unsigned int)&s.e );
    
    s.a = -1;
    s.b = 0x12345678;
    s.c = 'A';
    s.d = 1000;
    strcat ( s.e, "abcde" );

    t.b = 3;
    num = s.d * t.b;
    printf( "num = %d\n", num );

    return 0;

}    

Output

[~/courses/umbc/CMSC313/spring05/lectures/Lect10/structures1]$ structures1
size of s = 17
address of s = bfffd9c0
    address of s.a = bfffd9c0
    address of s.b = bfffd9c2
    address of s.c = bfffd9c6
    address of s.d = bfffd9c7
    address of s.e = bfffd9cb
num = 3000

Assembly Language

If you must match the C version (because someone else controls the composition of the struction), we can align the components on a boundary by using the alignb directive. gcc uses all double word boundarys. It is faster and in many cases can save bytes in the executable code.

Revised Code


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
section .data
struc   mystruct
	a:	resw	1
                alignb  4
	b:	resd	1
                alignb  4
	c:	resb	1
                alignb  4
	d:	resd	1
                alignb  4
	e:	resb	6
                alignb  4
endstruc

struct:
    istruc mystruct
        at a, dw        -1
        at b, dd        0x12345678
        at c, db        ' '
        at d, dd        23
        at e, db        'Gary', 0
    iend

mysize: dd     $ - struct
msg:    db     'Size of struct is %d', 10, 0
msg1:   db     'struct + b = %d', 10, 0
msg2:   db     'pStru + b = %d', 10, 0

zData:  dw     0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .bss
aBss:   resw    1

pStru:	resd	1         ; This is a pointer for a dynamically created structure

zBss:   resd    1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text
    global main
    extern printf
    extern scanf
    extern malloc

main:                                 

        push    dword [ mysize ]
        push    msg
        call    printf
        add     esp, 8

;; This is a static structure
	mov	eax, 7                    
	mov	dword [ struct + b ], eax  ; move a value into the structure
        push    dword [ struct + b ]       ; get the value
        push    dword msg1
        call    printf                     ; print it out
        add     esp, 8
        
;; This is a dynamic structure

        mov	eax, 17                    ; size of the structure
        push    eax
        call    malloc                     ; get the memory allocated
        mov     dword [ pStru ], eax       ; store the address in the pointer
        add     esp, 4

        mov	ebx, dword [ pStru ]       ; put the address into an index register
        mov     dword [ ebx + b ], 44h     ; set a value
        push    dword [ ebx + b ]          ; get the value
        push    dword msg2
        call    printf                     ; print it out
        add     esp, 8

        mov     ebx,0   ;successful termination of program
        mov     eax,1   ;system call number (sys_exit)
        int     0x80    ;call kernel

Output

[~/courses/umbc/CMSC313/spring05/lectures/Lect10/struct1]$ struct1
Size of struct is 24
struct + b = 7
pStru + b = 68


Previous | Next

©2004, Gary L. Burt