130 likes | 146 Views
Computer Architecture and System Programming Laboratory. TA Session 3. Stack - LIFO word-size data structure. RSP. STACK is temporary storage memory area RSP register points on top of stack (by default, it is highest RAM address) stack addresses go from high to low.
E N D
Computer Architecture and System Programming Laboratory TA Session 3
Stack - LIFO word-size data structure RSP • STACK is temporary storage memory area • RSPregister points on top of stack (by default, it is highest RAM address) • stack addresses go from high to low
Stack Operations • POP- load a value from the stack • reads the operand value at RSP address on stack (in Little Endian manner) • increment RSP by 2/4/8 bytes (according to operand size) • PUSH - push data on stack • decrements RSP by 2/4/8 bytes (according to the operand size) • stores the operand value at RSP address on stack (in Little Endian manner) • Example: • mov ax, 3 • push ax PUSHFQ -push value of RFLAGS into stack POPFQ- pop dword and stores it in RFLAGS • pop ax ; ax = 3 stack stack stack RSP RSP push ax pop ax RSP
inta,b,c,d,e,f,g; long longh,res; voidmain () { res = myFunc(a,b,c,d,e,f,g,h); } long longmyFunc (inta,intb,intc,intd,inte,intf,intg,long long h) { long long xx = 0, yy = 0; intzz = 0; … return xx;} • main: ; caller code • movrax, 0 ; unless we use floating-point point registers, we should initialize RAX to zero • movrdi, [a] ; push argument #1 • movrsi, [b] ; push argument #2 • movrdx, [c] ; push argument #3 • movrcx, [d] ; push argument #4 • mov r8, [e] ; push argument #5 • mov r9, [f] ; push argument #6 • push qword [h] ; push argument #8 • push dword [g] ; push argument #7 • call myFunc ; call the function push return address • add rsp, <argumentsSize> ; "delete" function arguments (argumentsSize = qword+dword= 12 bytes) • mov [res], rax … … … stack start of frame of main function RSP RSP RSP RSP RSP myFunc: ; callee code push rbp ; backup RBP movrbp, rsp ; reset RBP to current RSP sub rsp, <localsSize> ; allocate space for local variables (localsSize = 20 bytes) mov qword [rbp-8], 0 ; initialize a local variable xx mov qword [rbp-16], 0 ; initialize a local variable yy movdword [rbp-20], 0 ; initialize a local variable zz moveax, [rbp+16] ; get first argument movrbx, [rbp+20] ; get second argument ..... ; function code movrax, <returnValue> ; put return value into RAX movrsp, rbp ; move RBP to RSP pop rbp ; restore old RBP RET ; return from the function RBP RBP
Loop instruction LOOP, LOOPE, LOOPZ, LOOPNE, LOOPNZ – loop with counter (CX,ECX or RCX) Example:mov ax, 1 mov cx, 3 my_ loop: add ax, ax loop my_ loop, cx 1. decrements counter register 2. if counter does not become zero as a result of this operation, jump to the given label LOOPE ≡ LOOPZ: jumps if the counter ≠ 0 andZF = 1 LOOPNE ≡ LOOPNZ: jumps if the counter ≠ 0 and ZF = 0 Note: LOOP instruction does not set any flags Note: if a counter is not specified explicitly, the BITS setting dictates which is used.The BITS directive specifies whether NASM should generate code designed to run on a processor operating in 16-bit mode, 32-bit mode, or 64-bit mode. The syntax is BITS 16, BITS 32, or BITS 64.
Multiplication instruction MUL r/m - unsigned integer multiplication IMUL r/m - signed integer multiplication MUL r/m8 mov bl,5 ; multipliermov al,9 ; multiplicandmul bl ; ax 2Dh MUL r/m16 mov bx, 8000hmov ax, 2000hmul bx ; dx:ax 1000:0000h MUL r/m32 mov ebx, 80008000hmov eax, 20002000hmul ebx ; edx:eax 10002000:10000000h
Division instruction DIV r/m - unsigned integer division IDIV r/m - signed integer division For 32 bit division, we should use ‘cdq’ (convert double to quad) For 64 bit division, we should use ‘cqo’ (convert quad to oct) DIV r/m8 mov ax,0083h; dividendmov bl, 2h; divisorDIV bl ; al = 41h, ah = 01h ; quotient is 41h, remainder is 1 DIV r/m16 mov ax, 8003h; dividend, low cwd; convert word to double, copies the sign bit of AX into every bit of DX mov cx, 100h; divisor DIV cx ; ax = 0080h, dx = 0003h ; quotient = 80h, remainder = 3
<instruction> r/m8(16,32,64) 1/CL/imm8 Shift instruction • SHL, SHR – Bitwise Logical Shifts on first operand • number of bits to shift is given by second operand • vacated bits are filled with zero • (last) shifted bit enters the Carry Flag • Example: • mov CL , 3 • mov AL ,10110111b; AL = 10110111b • shr AL, 1 ; shift right 1 bit AL = 01011011b, CF = 1 • shr AL, CL ; shift right 3 bits AL = 00001011b, CF = 0 Note: shift indeed performsdivision / multiplication by 2 SAL, SAR – Bitwise Arithmetic Shift on first operand • vacated bits are filled with zero for SAL • vacated bits are filledwith copies of the original high bit of the source operand for SAR Example: mov CL , 3 mov AL ,10110111b sar AL, 1 ; shift right 1 AL = 11011011b sar AL, CL ; shift right 3 AL = 11111011b
<instruction> r/m8(16,32,64) 1/CL/imm8 Rotate instruction & constants ROL, ROR – bitwise rotate (i.e. moves round) on the first operand Example: mov CL, 3 mov BH ,10110111b; BH = 10110111b rol BH, 1 ; rotate left 1 bit BH = 01101111b rol BH, CL ; rotate left 3 bits BH = 01111011b RCL, RCR –bitwise rotate on first operand and Carry Flag Example: mov BH ,10110111b; BH = 10110111b , CF = 0 rcl BH, 1 ; rotate left 1 bit with CF BH = 01101110b , CF = 1 EQU - define constant Example: foo: EQU 1 ; foo = 1
TIMES-repeat (instruction or data) TIMES prefix causes the instruction to be assembled multiple times zeroBuf: times 64 db 0 ; 64 bytes initialized to 0 TIMES can be applied to ordinary instructions, so you can code trivial loopsmov EAX, 0times 100 inc EAX; EAX =100 => loop the argument to TIMES is not just a numeric constant, but a numeric expression buffer: db ‘go’ times 64-$+buffer db ‘!’ ; (64 - $ + buffer = 64 – 35 + 33 = 64 – 2 = 62) buffer + 64 $ (current position in the current section) buffer $$ (start of the current section) - start of section .data
gdb-GNU Debugger – very basic usage • run Gdb from the console by typing: gdb executableFileName • add breaking points by typing: break label • start debugging by typing: run parameters (argv) (gdb) set disassembly-flavor intel — change presentation of assembly-language instructions from the default Motorala conventions, that are used by gcc, to the Intel conventions that are used by nasm, that is, from opcode source, dest to opcode dest, src (gdb) layout asm — this will display the assembly language (gdb) layout regs – this will display registers • s/si – one step forward • c – continue to run the code until the next break point. • q – quit gdb • p/x $eax – prints the value in eax • x $esp+8 – prints the address in esp + 8 hexadecimal and the value (dword) that stores in this address. It is possible to use label instead of esp. Type x again will print the next dword in memory.
Assignment 1 - postfix-based calculator typedef struct bignum { long number_of_digits; char *digit; } bignum; • addition • subtraction • multiplication • division • arbitrary-precision integers • implement your own stack S (say, 1024 bytes sized array) Example: To compute 2 ∗ 3 + 4 ∗ 5, print the result, and quit, we input 2 3 * 4 5 * + p q • read input string char by char, ignoring any type of space characters • 2 will be pushed onto S • 3 will be pushed onto S • * will pop the top two elements on S, and push their product, 6, back onto S • 4 will be pushed onto S • 5 will be pushed onto S • * will pop the top two elements on S, and push their product, 20, back onto S • + will pop the top two elements on S, and push their sum, 26, onto S • p will print the result in base 10 (decimal) • q will quit the program Assume only correct input
Assignment 1 - postfix-based calculator ADC - add integers with carry (value of Carry Flag) Example:adc AX, BX;(AX gets a value of AX+BX+CF) SBB- subtract with borrow (value of Carry Flag) Example:sbb AX, BX;(AX gets a value of AX-BX-CF)