x86_64, which means it’s the 64-bit variant of the x86 architecture-- hello.c --> | Preprocessor | -- hello.i --> | Compiler | -- hello.s --> | Assembler | -- hello.o --> | Linker | -- hello -->
byte (suffix b) = 1 byte = 8 bitsword (suffix w) = 2 bytes = 16 bitsdouble word (suffix l) = 4 bytes = 32 bitsquad word (suffix q) = 8 bytes = 64 bitschar, short, int and long
To move into registers, between registers and between registers and memory, we use the mov instruction:
mov Source, Destination
movq Source, Destination
movb Source, DestinationThe Source and Destination above are what we call operands
There are three kinds:
$42 or $0x4F%rax(%rax)We’ll talk about the last kind more next time
Example:
movq $52, %rax
movq %rax, %rbxWe also have multiple two-operand arithmetic instructions: add, sub, imul, idiv, and, or, xor, etc.
They use the same general form as mov and perform the operation on the two operands and store the result in the Destination
E.g.,
addq $3, %rax
imul %rax, %rbxExercise: 14 * (10 + 3) - translate to assembly
There are also unary (single operand) instructions inc, dec, neg, not
The single operand is also the destination
jmp instruction (unconditional jump)To make decisions, we need to be able to jump conditionally
We can compare using the cmp instruction
cmp Sub, MinPerforms Min - Sub, but discards the result
Sub = subtrahend
Min = minuend
The next instruction is usually one of the following
je - jump if equaljne - jump if not equaljg - jump if Min > Subjge - jump if Min >= Subjl - jump if Min < Subjle - jump if Min <= SubThere are a few more, but these should be enough for us
When programming conditional jumps, always pay attention to how the cmp instruction works - in GNU assembly the sense is reversed
call instructionmain)call takes one operand – the address of the function’s body – most often we will use a symbolic name that represents that addressprintf is as simple as call printf… or is it?| Argument | Register |
|---|---|
| 1 | %rdi |
| 2 | %rsi |
| 3 | %rdx |
| 4 | %rcx |
| 5 | %r8 |
| 6 | %r9 |
%rax%rbx, %rbp, and %r12–%r15
all argument registers (see above), the return value register (%rax), %r10, %r11
These are best used as temporaries - they might “go bad” as soon as you call a function.
.global main # any symbols (e.g., functions) that should be visible
# outside this module, need to be declared global
.text # begin the executable code segment
main: # start of the main function
enter $0, $0 # set up the call stack (more next time)
# code
# ...
# code
# ...
# code
leave # clean up the stack space
ret # return from the function
# more functions ...
.data # beginning of the data segment
# - this is where global variables are defined
format_string:
.asciz "Hello, my age is: %d\n"
some_long_integer:
.quad 42