Assembly Language for Beginners

(Jeff_L) #1

1.24. STRUCTURES
1 _main PROC
2 push ebp
3 mov ebp, esp
4 sub esp, 12
5 mov BYTE PTR _tmp$[ebp], 1 ; set field a
6 mov DWORD PTR _tmp$[ebp+1], 2 ; set field b
7 mov BYTE PTR _tmp$[ebp+5], 3 ; set field c
8 mov DWORD PTR _tmp$[ebp+6], 4 ; set field d
9 sub esp, 12 ; allocate place for temporary structure
10 mov eax, esp
11 mov ecx, DWORD PTR _tmp$[ebp] ; copy 10 bytes
12 mov DWORD PTR [eax], ecx
13 mov edx, DWORD PTR _tmp$[ebp+4]
14 mov DWORD PTR [eax+4], edx
15 mov cx, WORD PTR _tmp$[ebp+8]
16 mov WORD PTR [eax+8], cx
17 call _f
18 add esp, 12
19 xor eax, eax
20 mov esp, ebp
21 pop ebp
22 ret 0
23 _main ENDP
24
25 _TEXT SEGMENT
26 _s$ = 8 ; size = 10
27 ?f@@YAXUs@@@Z PROC ; f
28 push ebp
29 mov ebp, esp
30 mov eax, DWORD PTR _s$[ebp+6]
31 push eax
32 movsx ecx, BYTE PTR _s$[ebp+5]
33 push ecx
34 mov edx, DWORD PTR _s$[ebp+1]
35 push edx
36 movsx eax, BYTE PTR _s$[ebp]
37 push eax
38 push OFFSET $SG3842
39 call _printf
40 add esp, 20
41 pop ebp
42 ret 0
43 ?f@@YAXUs@@@Z ENDP ; f


Now the structure takes only 10 bytes and eachcharvalue takes 1 byte. What does it give to us? Size
economy. And as drawback —the CPU accessing these fields slower than it could.

The structure is also copied inmain(). Not field-by-field, but directly 10 bytes, using three pairs ofMOV.
Why not 4?

The compiler decided that it’s better to copy 10 bytes using 3MOVpairs than to copy two 32-bit words and
two bytes using 4MOVpairs.

By the way, such copy implementation usingMOVinstead of calling thememcpy()function is widely used,
because it’s faster than a call tomemcpy()—for short blocks, of course:3.11.1 on page 511.

As it can be easily guessed, if the structure is used in many source and object files, all these must be
compiled with the same convention about structures packing.

Aside from MSVC/Zpoption which sets how to align each structure field, there is also the#pragma pack
compiler option, which can be defined right in the source code. It is available in both MSVC^164 and GCC^165.

Let’s get back to theSYSTEMTIMEstructure that consists of 16-bit fields. How does our compiler know to
pack them on 1-byte alignment boundary?

WinNT.hfile has this:

Listing 1.343: WinNT.h
#include "pshpack1.h"

(^164) MSDN: Working with Packing Structures
(^165) Structure-Packing Pragmas

Free download pdf