1.5. HELLO, WORLD!
The listing contains many macros (the parts that begin with a dot). These are not interesting for us at the
moment.
For now, for the sake of simplicity, we can ignore them (except the.stringmacro which encodes a null-
terminated character sequence just like a C-string). Then we’ll see this^22 :
Listing 1.19: GCC 4.7.3
.LC0:
.string "hello, world\n"
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
ret
Some of the major differences between Intel and AT&T syntax are:
- Source and destination operands are written in opposite order.
In Intel-syntax: <instruction> <destination operand> <source operand>.
In AT&T syntax: <instruction> <source operand> <destination operand>.
Here is an easy way to memorize the difference: when you deal with Intel-syntax, you can imagine
that there is an equality sign (=) between operands and when you deal with AT&T-syntax imagine
there is a right arrow (→)^23.
- AT&T: Before register names, a percent sign must be written (%) and before numbers a dollar sign
($). Parentheses are used instead of brackets. - AT&T: A suffix is added to instructions to define the operand size:
- q — quad (64 bits)
- l — long (32 bits)
- w — word (16 bits)
- b — byte (8 bits)
To go back to the compiled result: it is almost identical to what was displayed byIDA. There is one subtle
difference: 0FFFFFFF0his presented as$-16. It’s the same thing: 16 in the decimal system is0x10in
hexadecimal.-0x10is equal to0xFFFFFFF0(for a 32-bit data type).
One more thing: the return value is set to 0 by using the usualMOV, notXOR.MOVjust loads a value to a
register. Its name is a misnomer (as the data is not moved but rather copied). In other architectures, this
instruction is named “LOAD” or “STORE” or something similar.
String patching (Win32)
We can easily find the “hello, world” string in the executable file using Hiew:
(^22) This GCC option can be used to eliminate “unnecessary” macros:-fno-asynchronous-unwind-tables
(^23) By the way, in some C standard functions (e.g., memcpy(), strcpy()) the arguments are listed in the same way as in Intel-syntax:
first the pointer to the destination memory block, and then the pointer to the source memory block.