Practical Session 3
Feb 06, 2016
Practical Session 3
Advanced Instructions
DIV r/m - unsigned integer multiplication
DIV r/m8mov ax,0083h ; dividendmov bl, 2h ; divisorDIV bl ; al = 41h, ah = 01h
; quotient is 41h, remainder is 1
DIV r/m16 mov dx,0 ; clear dividend, high mov ax, 8003h ; dividend, low mov cx, 100h ; divisor DIV cx ; ax = 0080h, dx = 0003h
; quotient = 80h, remainder = 3
Dividend Divisor Quotient Remainder
AX r/m8 AL AH
DX:AX r/m16 AX DX
EDX:EAX r/m32 EAX EDX
SHL, SHR – Bitwise Logical Shifts on the first operand– number of bits to shift by is given by the second operand
– vacated bits are filled with zero
– shifted bit enters the Carry Flag
SHL r/m8/m16/m32 1/CL/imm8SHR r/m8/m16/m32 1/CL/imm8
Example:
mov CL , 3
mov AL ,10110111b ; AL = 10110111
shr AL, 1 ; shift right 1 AL = 01011011, CF = 1
shr AL, CL ; shift right 3 AL = 00001011, CF = 0
Note: that shift indeed performs division/multiplication by 2
Advanced Instructions
SAL, SAR – Bitwise Arithmetic Shifts on the first operand– vacated bits are filled with zero for SAL– vacated bits are filled with copies of the original high bit of the source operand for SAR
SAL r/m8/m16/m32 1/CL/imm8SAR r/m8/m16/m32 1/CL/imm8
Example:
mov CL , 3
mov AL ,10110111b ; AL = 10110111
sar AL, 1 ; shift right 1 AL = 11011011
sar AL, CL ; shift right 3 AL = 11111011
Advanced Instructions
SAL 10000001b ; the result is 00000010b and this is right result!How? The below explains this.
10000001b = -12711111111b = -1(-127) + (-1) = 10000001b + 11111111b = 10000000b = -128(-128) + (-1) = 10000000b + 11111111b = 01111111b = 127Since the range of 8 bit signed arithmetic is -128 : 127 it is natural that -128-1 = 127 and that 127 + 1 = -128. SAL 10000001b = SAL -127 = -127 * 2 = -127 -127 = -128 – 1 – 125 = 127 – 125 = 2 = 00000010b
ROL, ROR – Bitwise Rotate (i.e. moves round) on the first operand
ROL r/m8/m16/m32 1/CL/imm8ROR r/m8/m16/m32 1/CL/imm8
Example:
mov CL, 3
mov BH ,10110111b ; BH = 10110111
rol BH, 01 ; rotate left 1 bit BH = 01101111
rol BH, CL ; rotate left 3 bits BH = 01111011
Advanced Instructions
RCL, RCR – Bitwise Rotate through Carry Bit on the first operand and Carry Flag
RCL r/m8/m16/m32 1/CL/imm8RCR r/m8/m16/m32 1/CL/imm8
Example:
mov BH ,10110111b ; BH = 10110111 , CF = 0
rcl BH, 01 ; rotate left 1 bit BH = 01101110 , CF = 1
Advanced Instructions
LOOP, LOOPE, LOOPZ, LOOPNE, LOOPNZ – loop with counter (CX or ECX*)
Example: mov ax, 1 mov cx, 3 my_ loop: add ax, ax LOOP my_ loop, cx
1. decrements its counter register (in this case it is CX register)
2. if the counter does not become zero as a result of this operation, it jumps to the given label
* 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, or code designed to run on a processor operating in 32-bit mode. The syntax is BITS 16 or BITS 32.
Note: LOOP instruction does not set any flags
LOOPE ≡ LOOPZ: jumps if the counter is nonzero and Zero Flag = 1
LOOPNE ≡ LOOPNZ: jumps if the counter is nonzero and Zero Flag = 0
Advanced Instructions
The Stack
• The stack is an area in memory that its purpose is to provide a space for temporary storage of addresses and data items
• Every cell in the stack is of size 2 or 4 bytes
• The register ESP holds the address that points to the top of the stack
Read-only Data Segment
.bss
.data
.text .rodata
ESP
Stack Operations
• PUSH
Push data on stack.– It decrements the stack pointer ESP, and then stores the given value at ESP (in
little endian order)
– The size of the operand determine whether the stack pointer is decremented by 2 or 4
Example
mov ax, 0x21AB
push ax
ESP
0x21
0xAB
stack
ESP
stackESP
stack
dec ESP by 2 bytes (size of ax)
store ax value in little endian manner
• PUSHAD (also PUSHA )Push All General-Purpose Registers into stack.
– PUSHAD pushes, in succession, EAX, ECX, EDX, EBX, ESP, EBP, ESI and EDI on the stack, decrementing the stack pointer by a total of 32
– the value of ESP pushed is its original value, as it had before the instruction was executed.
Note that the registers are pushed in order of their numeric values in opcodes.
• PUSHFD (also PUSHF)
Push the entire flags register onto the stack
ESPstack
ESP
stack
PUSHADEAX
ECX
EDX
EBX
ESP
EBP
ESI
EDI
ESP
stack
PUSHFDEAX
ECX
EDX
EBX
ESP
EBP
ESI
EDI
EFLAGS
• POP
Load a value from the stack.– starting from [ESP] address, and then increments the stack pointer by 2 or
4
– The size of the operand determine whether the stack pointer is incremented by 2 or 4
Examplemov ax, 3
mov bx, 0x12AF
push ax
push bx
pop ax ; ax = 0x12AF
pop bx ; bx = 3
ESP
0x00
0x03
stack
ESP
0x00
0x03
0x12
0xAF
stackESP
stack
push axpush bx
pop axESP
stack
pop bx
• POPAD (also POPA)
Pop All General-Purpose Registers.– POPAD pops a dword from the stack into each of, successively, EDI, ESI, EBP,
nothing (placeholder for ESP), EBX, EDX, ECX and EAX
• POPFD (also POPF)
Pop Flags Register. – POPFD pops a dword and stores it in the entire flags register.
ESP
stackEAX
ECX
EDX
EBX
ESP
EBP
ESI
EDI
ESPstack
POPFD
Function calls - Stack Frame
stack
local variables
space
main: ; caller codepushad ; backup registerspush dword 2 ; push argument #2push dword 1 ; push argument #1CALL myFunc ; call the function the address of the next instruction of callercaller
; (i.e. return address) is pushed automatically onto the stackmov [answer], eax ; retrieve return value from EAXadd esp, argumentsSize ; "delete" function arguments (in our case argumentsSize = 2 * dword = 8 bytes)popad ; restore registers
myFunc: ; callee codepush ebp ; backup EBPmov ebp, esp ; reset EBP to the current ESPsub esp, localsSize ; allocate space for localsmov ebx, [ebp+12] ; get second argumentmov ecx, [ebp+8] ; get first argumentmov [ebp-4], ebx ; initialize c local... ; function codemov eax, ... ; put return value into EAXmov esp, ebp ; move EBP to ESPpop ebp ; restore old EBPRET ; return from the function
PUSHAD
2
1
return address
EBP
…
EBP + 12
EBP
ESP
EBP + 8
EBP - 4
In Linux, we receive command-line arguments on the stack as execution starts:
- the first argument is number of arguments (i.e. argc)
- the rest of the arguments – each one is a pointer to an argument string (i.e. argv[0], argv[1], argv[2] and so on)
Command Line Arguments
Gdb-GNU Debugger
Run Gdb from the console by typing gdb executeFileName
Adding a breaking point by typing:
break label Start debugging by typing:
run parameters (for argv)
Gdb syntax• si – one step forward
• c – continue to run the code until the next break point.
• q – quit gdb
• p $eax – prints the value in eax
• x $esp+4 – prints the address in esp + 4 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.
Task 1
In this task we would use task1.s assembly file and main1.c - C file.
Write a program that gets a string containing hexadecimal digits and convert it to an unsigned ternary (3 base) number.
You can get up to 8 hexadecimal digits.
Example:
Input: 2ABC Output: 120000012
*This time you are to ignore the input character ‘\n’.
(loop’s stop rule accordingly)
You have to convert the output number to a string.
Task 2
Practice parameters passing from assembly to C and vice versa.
You are to write a C program that performs:
• Prompts for and reads a integer (32 bit) x (decimal) from the user .
• Calls a function isDivisibleBy3(int x) written in ASSEMBLY.
An assembly function ‘isDivisibleBy3' that performs:
• Sum the even bits of x.
• Sum the odd bits of x.
• Call C function 'check' as defined below.
• If check returns 1: calls printf to print: "the number is divisible by 3", and returns.
• If check returns -1: calls printf to print: "the number is not divisible by 3" and returns.
• Otherwise does not print anything, and returns.
The C function ‘check(int evenBits, int oddBits)’performs:
•Gets 2 arguments: integers evenBits and oddBits
•Calculate the absolute value of evenBits-oddBits
•If the result is zero returns 1.
•If the result is 1 or 2 returns -1.
•Otherwise call 'isDivisibleBy3(int y)' where y = absolute value of evenBits-oddBits *
•Returns 0.
* This manner of programming is called mutual recursion
We suggest to backup your parameters on the stack!
Task 2
main1.c file#include <stdio.h>
#define BUFFER_SIZE (128)
extern int my_func(char* buf);
int main(int argc, char** argv){
char buf[BUFFER_SIZE];
printf("Enter string: ");
fflush(stdout);
fgets(buf, BUFFER_SIZE, stdin);
printf("Got string: %s\n", buf);
my_func(buf);
return 0;
}
1. Include stdio.h library (standard I/O)
2. Get online parameters (from the user)
3. Call to an assembly function “my_func”
Note: It can contain other functions that we can call from an assembly file
Task1.s filesection .rodataLC0:
DB "The result is: %s, 10, 0Section .bssLC1:
resb 32section .text
align 16global my_funcextern printf
my_func:push ebpmov ebp, esppush ecx
mov ecx, dword [ebp+8]
; Your code should be here...
push LC1push LC0call printfadd esp, 8
pop ecxmov esp, ebppop ebpret
1. Has 3 sections: .rodata , .text, .bss.2. Align 16 means that all data and instruction should be at an address that is divided by 16 (bits) (in another words, an address should be even)
3. my_func is a function that we define; it should be global so that main.c file would be able to call to it
4. We use printf function of stdio.h C library; so we should declare it as an external function because it isn’t defined in our assembly file (if we use any function that is not in our file, we should declare it as external)
5. The purpose of my_func is to call printf with the string it got from main as an argument.
section .rodataLC0:
DB "The result is: %s", 10, 0 ; Format stringSection .bssLC1:
resb 32
section .textalign 16global my_funcextern printf
my_func:push ebpmov ebp, esp ; Entry code - set up ebp and esppusha ; Save registers
mov ecx, dword [ebp+8] ; Get argument (pointer to string)
; Your code should be here...
push LC1 ; Call printf with 2 arguments: a numberpush LC0 ; and pointer to format string.call printfadd esp, 8 ; Clean up stack after call
popa ; Restore registersmov esp, ebp ; Function exit codepop ebpret
The structure of programs in the tasks