Lecture 9 1 x86 64 Instructions April 29, 2015 Alignment • As mentioned previously, we will use 8 bytes (64 bits) for all non-structure data types. This is a terribly simplistic approach. • As such, all data will be implicitly 8-byte aligned. • End of input argument area of stack frame is 16-byte aligned (by ABI). 2 Instruction Set • See handout. 3 Subroutines • Subroutines will begin with a prologue to setup the stack. .text .global main .type main, @function main: pushq %rbp movq %rsp, %rbp ; store callee-saved registers (pushq) subq $56, %rsp – Set following section as executable text (setting stays until another .section pseudo-operation is specified). – Make name accessible externally. – Specify the type for the linker. – Define the function. – Save stack pointer (rsp) as frame pointer (rbp). – Move stack pointer. • Each subroutine also has an epilogue. addq $56, %rsp ; only if stored registers ; restore callee-saved registers (popq) movq %rbp, %rsp popq %rbp ret .size main, .-main – – – – – Move stack pointer to saved registers. Pop callee-saved registers. Restore prior stack pointer. Restore prior frame pointer. Set size of subroutine (diff of current location and initial def of main). 1 4 Globals • When generating assembly, we don’t necessarily know where a global variable will be placed (and therefore what it’s address will be). • Actual addressing will be taken care of by the linker (and then the loader). • This is good. It means that the assembly can just use symbols. • A global can be defined by a .comm directive (specifying the size and alignment). .comm glob i,8,8 • This symbol can then be coupled with the rip register to create an address. movq glob i(%rip), %rdx • Value is now in %rdx. • Can use name as immediate to store the address in a register. movq 5 $glob i, %rdx Strings (printf/scanf ) • Similar to the idea above. Create a label that corresponds to the desired string. .section .rodata .LLC0: .string "%ld\n" • Then use that label to get the address of the string. mov mov mov call $.LLC0, %rdi $0, %rsi $0, %rax printf ; for varargs functions -- # of vector registers used • Same idea for scanf, but need address for second argument. 2 Sampling Arithmetic addq subq imulq imulq idivq (r1 | i32 | mem), (r2 | mem) (r1 | i32 | mem), (r2 | mem) (r1 | mem), r2 i32 , (r1 | mem), r2 (r | mem) r2 += r1 r2 -= r1 r2 *= r1 r2 = r1 * i rax = rdx:rax / r, rdx = rdx:rax % r Boolean andq orq xorq (r1 | i32 ), r2 (r1 | i32 ), r2 (r1 | i32 ), r2 r2 &= r1 r2 |= r1 r2 ∧= r1 Comparison and Branching cmp jmp je jg jge jl jle jne (r1 | i32 ), r2 label label label label label label label tmp = r2 - r1, sets flags Loads and Stores movq disp(base, offset, scalar), r movq (r | i32 ), disp(base, offset, scalar) load from base + offset * scalar + disp into r store from r to base + offset * scalar + disp Invocation call ret label Conditional Moves cmoveq (r1 cmovgq (r1 cmovgeq(r1 cmovlq (r1 cmovleq (r1 cmovneq(r1 | | | | | | mem), mem), mem), mem), mem), mem), r2 r2 r2 r2 r2 r2 move move move move move move if if if if if if equal greater greater or equal less less or equal not equal Shifts shrq cl, (r | mem) logical right shift cl times