Experiment with code examples
- Log into your Linux account on one of the CS machines.
- Create a directory for your lab08 experiments.
- Create a text or word document for your notes (turn in at the end!)
- Create a C program
code.c containing just the following code:
int accum = 0;
int sum(int x, int y)
{
int t = x + y;
accum += t;
return t;
}
- Generate assembly language code from this program using the C compiler. The
-S option
means to only generate assembly code and stop. We will also use the -Og (capital O, not zero)
to tell the compiler to use only basic optimizations.
gcc -m64 -Og -S code.c
- Examine the resulting code.s to and try to figure out what it does.
- Repeat this experiment, leaving out the -m64 (or try with -m32 if 64-bit is your default).
- Repeat this experiment, leaving out the
-Og. Notice that the
generated code is more complex (but potentially more efficient). Try -O0, -O1, -O2 instead of -Og. See the bottom of
this lab for an explanation.
- Use the
-c compiler option to both compile and assemble the code:
gcc -m64 -Og -c code.c
- Use
objdump to disassemble the resulting object code:
objdump -d code.o
- The output of disassembly is the actual bytes in the object code in the left column,
and the equivalent assembly language in the right column.
- Type
objdump alone to see the help. Experiment with other options
that might be useful.
- We can see the exact byte representation of our
sum function using the debugger:
gdb code.o
(gdb) x/17xb sum
(gdb) quit
x/17xb means to examine 17 hex-formatted bytes.
Executable Code
Generating actual executable code requires running a linker.
- Add the following code to a file named
main.c
int main()
{
return sum(1, 3);
}
- Generated the executable program as follows:
gcc -m64 -Og -o prog code.o main.c
- What size in bytes is the resulting file? Why?
- Disassembly the resulting file:
objdump -d prog
A related example
Look at the resulting assembly code for the following function:
int simple(int *xp, int y)
{
int t = *xp + y;
*xp = t;
return t;
}
ATT vs Intel Assembly Code Formats
There are some differences in AT&T formatting and Intel formatting, even for the
same assembly language. To see the Intel assembly for the original code.c:
gcc -m64 -Og -S -masm=intel code.c
- What do you notice that's different?
Experiment with Memory and Arithmatic Instructions
Keep detailed notes of each experiment!
long test(long x, long y) {
// body
}
return:
x + y
x - y
x >> y
x * y
x * 13
x | y
~x
Trickier ones:
!x
x || y, x && y
Try x >> y with unsigned long for return value and arguments
Try a couple of the above experiments with int, short, or char datatypes instead of long
BE CAREFUL - the compiler is too smart!!
e.g.
x++
y++
return x+y;
Questions:
- What register holds the first argument?
- What register holds the second argument?
- What register holds the third argument?
- What register holds 4, 5, 6 arguments?
- Try a method with 8 or 9 arguments - now what happens?
- What register holds the return value?
Memory:
Use pointers to load something from memory.
Use pointers to save something to memory.
Create an array and access its elements
Create a struct and access its elements
If you have time:
do while loop
while loop
for loop
if without an else
if/else
Appendix: gcc Optimization flags:
From the man page:
-O (Same as -O1)
-O0 (do no optimization, the default if no optimization level is specified)
-O1 (optimize minimally)
-O2 (optimize more)
-O3 (optimize even more)
-Ofast (optimize very aggressively to the point of breaking standard compliance)
-Og (Optimize debugging experience. -Og enables optimizations that do not interfere with debugging. It should be the
optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization
while maintaining fast compilation and a good debugging experience.)
-Os (Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations
designed to reduce code size.
-Os disables the following optimization flags: -falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version)
|