Reputation: 105
I have the following code. Can someone please explain the questions that I have in the parenthesis?
# Execution begins at address 0 (why?)
.pos 0
irmovq stack, %rsp # Set up stack pointer (how can i move the word "stack" in rsp)
call main # Execute main program
halt # Terminate program
# Sample linked list (what is the purpose of .align 8?)
.align 8
ele1:
.quad 0x00a
.quad ele2
ele2:
.quad 0x0b0
.quad ele3
ele3:
.quad 0xc00
.quad 0
main:
irmovq ele1,%rdi
call sum
ret
sum:
# Stack starts here and grows to lower addresses
.pos 0x100
stack:
Upvotes: 0
Views: 5294
Reputation: 16586
.pos <adr>
is directive to change current virtual address for compiler. So the next instruction compiled will be treated as at address <adr>
, if you will put <label>
ahead of it, the <label>
will have value <adr>
, thus any instruction later in code operating with absolute address of <label>
will be compiled with <adr>
value.
Also compiler keeps track of current virtual address during compilation, so if you use some <label2>
few instructions later, it will have <adr + size_of_produced_machine_code_so_far>
value.
When you then load the machine code at that position in real memory, all the absolute addresses in the code will fit and work correctly (if you load it elsewhere, it won't work correctly, as the instructions will still refer to the <adr>
, for which they were compiled).
In your example it means that first irmovq
is expected to be placed at address 0
, once that machine code is loaded into memory computer.
Why execution starts from address 0? Who knows, that's the feature of the target platform. If the target platform would start to execute from 0x300, it would make sense to put start-up code there instead, with .pos 0x300
directive.
irmovq stack, %rsp # Set up stack pointer (how can i move the word "stack" in rsp)
rsp
is set to contain address of stack
symbol (actually it's value of "stack" symbol, which can be seen as memory address in human logic, but it's just number, as everything in computer), which is 0x100
value (because of .pos
directive right ahead of that stack:
label definition). So that instruction does rsp = 0x100
.
what is the purpose of
.align 8
?
Alignment means to adjust the address, to be divisible with certain number without remainder. In the first case the label ele1
will have address divisible by 8. If the previous machine code would end at some non-divisible address, compiler will add some bytes (usually nop
-like instructions) to fill the gap till the next possible address fulfilling the align
requirements.
Alignment is important for memory controller performance, as they usually work with group of bytes internally, like being able to fetch quad-word as 8 bytes only from 8-aligned address. If you ask it to fetch quad-word from non-aligned address, it will fetch two 8-byte sets from (address & -8)
and ((address & -8)+8)
, and read the final 8 byte result from the middle of those fetched 16 bytes. (on x86 .. on other platforms unaligned memory access can be even invalid operation, causing the CPU to receive trap-signal, to run crash handler in such case).
(why bitwise AND with -8 makes the address 8-aligned? -8 = 0xF..F8 = 0b11...11000 => last 3 bits set to zero => divisible by 8 enforced)
Upvotes: 2
Reputation: 34585
Execution starts at 0
because that is what .pos 0
does on the next line.
The word "stack" is not moved: stack
it is a label further down in the code, which sets the stack pointer rsp
to that location in memory.
The purpose of aligning to 8-byte boundaries is because the processor does not take kindly to bridging such a boundary. The .quad
directive generates 8-byte data.
It is off topic to ask for tutorials - it is very easy to google them and go with one you feel is right for you.
Upvotes: 1