Practical Session 5 Addressing Modes x 86 provides

  • Slides: 19
Download presentation
Practical Session 5

Practical Session 5

Addressing Modes • x 86 provides a flexible scheme for computing and referring to

Addressing Modes • x 86 provides a flexible scheme for computing and referring to memory addresses. • x 86 addressing mode rule : up to two of the 3 -bit registers and a 32 -bit signed constant can be added together to compute a memory address. One of the registers can be optionally pre-multiplied by 2, 4, or 8. Example of right usage • mov dword [my. Array + ebx*4+eax], ecx Examples of wrong usage

Addressing Modes • Register Addressing operate on a variable or intermediate variable inc eax

Addressing Modes • Register Addressing operate on a variable or intermediate variable inc eax • Immediate Addressing operate on a CONSTANT add ax, 0 x 4501 • Absolute (Direct) Addressing specify the address as a number or label inc word [my. String] inc word [0 x 1000] • Register Indirect Addressing inc byte [ebx] • Displacement Addressing Effective Address=[register]+displacement inc byte [ebx+0 x 10] • Relative Addressing Effective Address =[PC]+ displacement jnz next ; ≡ jnz $+4 inc eax next: neg eax • Indexed Addressing (with Displacement) useful for array indices inc dword [ebx*4] inc dword [ebx*4+eax] inc dword [my. Array + ebx*4+eax]

Addressing Modes - Example #include <stdio. h> #define VECTOR_SIZE 5 extern long* Dot. Product

Addressing Modes - Example #include <stdio. h> #define VECTOR_SIZE 5 extern long* Dot. Product (int V 1[VECTOR_SIZE], int V 2[VECTOR_SIZE], int size); int main () { int V 1[VECTOR_SIZE] = {1, 0, 2}; int V 2[VECTOR_SIZE] = {1, 0, -2}; long* result = Dot. Product(V 1, V 2, VECTOR_SIZE); printf ("Dot product result: %#llx n ", result); return 0; }

 int V 1[VECTOR_SIZE] = {1, 0, 2}; int V 2[VECTOR_SIZE] = {1, 0,

int V 1[VECTOR_SIZE] = {1, 0, 2}; int V 2[VECTOR_SIZE] = {1, 0, -2}; long* result = Dot. Product(V 1, V 2, VECTOR_SIZE); stack VECTOR_SIZE EBP + 16 EBP + 12 EBP + 8 EBP V 2 V 1 return address EBP previous value old ebx old ecx ESP old edx next element of vector V 1 next element of vector V 2 section. data result: dd 0, 0 section. text global Dot. Product: push mov push mov Dot. Product_start: mov cmp je mov mov imul add adc inc jmp Dot. Product_end: mov pop pop mov pop ret ebp, esp ebx ecx edx ecx, 0 edx, 0 ecx, dword [ebp+16] Dot. Product_end ebx, dword [ebp+8] eax, dword [ebx + (4*ecx)] ebx, dword [ebp+12] dword [ebx + (4*ecx)] dword [result], eax dword [result+4], edx ecx Dot. Product_start eax, result ; return value edx ecx ebx esp, ebp

Linux System Calls q System calls are low level functions the operating system makes

Linux System Calls q System calls are low level functions the operating system makes available to applications via a defined API (Application Programming Interface) q System calls represent the interface the kernel presents to user applications. q In Linux all low-level I/O is done by reading and writing file handles, regardless of what particular peripheral device is being accessed - a tape, a socket, even your terminal, they are all files. Files are referenced by an integer file descriptor. q Low level I/O is performed by making system calls

Anatomy of System Calls q A system call is explicit request to the kernel

Anatomy of System Calls q A system call is explicit request to the kernel made via a software interrupt q The interrupt call ‘ 0 x 80’ call to a system call handles q To perform Linux system calls we have to do following: q. Put the system call number in EAX register q. Set up the arguments to the system call. The first argument goes in EBX, the second in ECX, then EDX, ESI, EDI, and finally EBP. If more then 6 arguments needed (not likely), the EBX register must contain the memory location where the list of arguments is stored. qcall the relevant interrupt (for Linux it is 0 x 80) q. The result is usually returned in EAX

sys_open - open a file • system call number (in EAX): 5 • arguments:

sys_open - open a file • system call number (in EAX): 5 • arguments: – EBX: pathname of the file to open/create – ECX: set file access bits (can be bitwise OR’ed together) • • • O_RDONLY open for reading only O_WRONLY open for writing only O_RDRW open for both reading and writing O_APPEND open for appending to the end of file O_TRUNC truncate to 0 length if file exists O_CREAT create the file if it doesn’t exist – EDX: set file permissions (in case of create; can be bitwise OR’ed together) • • • S_IRWXU 0000700 ; RWX mask for owner S_IRUSR 0000400 ; R(read) for owner USR(user) S_IWUSR 0000200 ; W(write) for owner S_IXUSR 0000100 ; X(execute) for owner returns (in EAX): – file descriptor. – On errors: -1. section. data file. Name: db “file. txt", 0 handle dd 0 section. text global _start: file_open: mov eax, 5 ; system call number (sys_open) mov ecx, 1 ; set file access bits (O_WRONLY) mov ebx, file. Name ; set file name mov edx, S_IRUSR ; set file permissions int 0 x 80 ; call kernel mov [handle], eax ; move file handle to memory mov eax, 1 mov ebx, 0 int 0 x 80 ; system call number (sys_exit) ; exit status ; call kernel

sys_read – read into a file • system call number (in EAX): 3 •

sys_read – read into a file • system call number (in EAX): 3 • arguments: – EBX: file descriptor – ECX: pointer to input buffer – EDX: maximal number of bytes to receive (buffer size) • returns (in EAX): • number of bytes received • On errors: -1 or 0 (no bits read) section . bss buffer: resb 1 section . text global _start: mov eax, 3 mov ebx, 0 mov ecx, buffer mov edx, 1 int 0 x 80 ; system call number (sys_read) ; file descriptor (stdin) ; buffer to put the read data ; read byte count ; call kernel mov eax, 1 mov ebx, 0 int 0 x 80 ; system call number (sys_exit) ; exit status ; call kernel

sys_write – write into a file • system call number (in EAX): 4 •

sys_write – write into a file • system call number (in EAX): 4 • arguments: – EBX: file descriptor – ECX: pointer to the first byte to read (beginning of the string) – EDX: number of bytes (characters) to write • returns (in EAX): • number of bytes written • On errors: -1 section . data msg db ‘Message', 0 xa len equ $ - msg ; our string ; length of our string section . text global _start: mov ebx, 1 mov ecx, msg mov edx, len mov eax, 4 int 0 x 80 ; file descriptor (stdout) ; message to write ; message length ; system call number (sys_write) ; call kernel mov eax, 1 mov ebx, 0 int 0 x 80 ; system call number (sys_exit) ; exit status ; call kernel

sys_lseek – change a file pointer • • system call number (in EAX): 19

sys_lseek – change a file pointer • • system call number (in EAX): 19 arguments: – EBX: file descriptor – ECX: offset (number of bytes to move) – EDX: where to move from • • SEEK_SET 0 ; beginning of the file SEEK_CUR 1 ; current position of the file pointer SEEK_END 2 ; end of file returns (in EAX): – Current position of the file pointer – On errors: SEEK_SET section. data file. Name: db “file. txt", 0 handle dd 0 section. text global _start: file_open: mov eax, 5 ; system call number (sys_open) mov ecx, 1 ; set file access bits (O_WRONLY) mov ebx, file. Name ; set file name mov edx, S_IRUSR ; set file permissions int 0 x 80 ; call kernel mov [handle], eax ; move file handle to memory mov ecx, 15 ; number of byte to move mov edx, 0 ; move from beginning of the file mov eax, 19 ; the number of the syscall 'lseek‘ int 0 x 80 ; call kernel mov eax, 1 mov ebx, 0 int 0 x 80 ; system call number (sys_exit) ; exit status ; call kernel

sys_close – close a file • system call number (in EAX): 6 • arguments:

sys_close – close a file • system call number (in EAX): 6 • arguments: – EBX: file descriptor • returns (in EAX): • nothing meaningful • On errors: -1 section. data file. Name: db “file. txt", 0 handle dd 0 section. text global _start: file_open: mov eax, 5 ; system call number (sys_open) mov ecx, 1 ; set file access bits (O_WRONLY) mov ebx, file. Name ; set file name mov edx, S_IRUSR ; set file permissions int 0 x 80 ; call kernel mov [handle], eax ; move file handle to memory mov ebx, [handle] mov eax, 6 int 0 x 80 mov eax, 1 mov ebx, 0 int 0 x 80 ; system call number (sys_exit) ; exit status ; call kernel

Linux System Calls - Example section. data file. Name: db “file. txt", 0 handle

Linux System Calls - Example section. data file. Name: db “file. txt", 0 handle dd 0 section. bss buffer: resb 1 section. text global _start _exit: mov ebx, [handle] mov eax, 6 int 0 x 80 ; system call (sys_close) ; call kernel mov eax, 1 mov ebx, 0 int 0 x 80 ; system call (sys_exit) ; exit status ; call kernel _start: mov eax, 5 ; system call (sys_open) mov ecx, 1 ; set file access bits (O_WRONLY) mov ebx, file. Name ; set file name mov edx, S_IRUSR ; set file permissions int 0 x 80 ; call kernel mov [handle], eax ; move file handle to memory mov eax, 3 mov ebx, [handle] mov ecx, buffer mov edx, 1 int 0 x 80 cmp eax, 0 je _exit ; system call (sys_read) ; file handle ; buffer ; read byte count ; call kernel mov eax, 4 mov ebx, 1 mov ecx, buffer mov edx, int 0 x 80 ; system call (sys_write) ; stdout ; buffer ; write byte count ; call kernel jmp _start

Assignment #2 • Writing a simple calculator for unlimited-precision integers. • Operators: – –

Assignment #2 • Writing a simple calculator for unlimited-precision integers. • Operators: – – – Addition unsigned (+) Pop-and-print (p) Duplicate (d) Log 2 (l) Number of '1' bits (n) Quit (q) • Operands in the input and output will be in hexadecimal

Assignment #2 • The calculator uses Reverse Polish Notation (RPN) – i. e. every

Assignment #2 • The calculator uses Reverse Polish Notation (RPN) – i. e. every operator follows all of its operands Example: 1 2 + 10 l 4 n 1+2 log 2 (10) (indeed results with log 2(8)) number of ‘ 1’ bits in 4 • Operands in the calculator are implicit – taken from a stack • The stack data type is implemented by you

Assignment #2 >>calc: 09 >>calc: 1 >>calc: d >>calc: p >>01 >>calc: + >>calc:

Assignment #2 >>calc: 09 >>calc: 1 >>calc: d >>calc: p >>01 >>calc: + >>calc: d >>calc: p >>0 A TOS -> Stack 09 0 A TOS -> 01 TOS ->

Assignment #2 >>calc: n >>calc: p TOS -> Stack 0 A TOS -> 02

Assignment #2 >>calc: n >>calc: p TOS -> Stack 0 A TOS -> 02 >>calc: + Error: Not Enough Arguments in Stack

Assignment #2 • Your program should be able to handle an unbounded operand size.

Assignment #2 • Your program should be able to handle an unbounded operand size. This may be implemented as a linked list: – each element represents 2 hexadecimal digits in the number. – an element block is composed of a 4 byte pointer to the next element, and a byte data. Example: 0 x 7 D 12 AF could be represented by the following linked list: AF 12 7 D 0 • Using this representation, each stack element is simply a list head pointer.

Assignment #2 • • • Declare a label "main: " and "global main" in

Assignment #2 • • • Declare a label "main: " and "global main" in your assembly program. Declare "extern printf, extern malloc" and "extern gets" so you will be able to use those functions in the program Compile and link your assembly file calc. s as follows: nasm -f elf calc. s -o calc. o gcc -m 32 -Wall -g calc. o -o calc. bin Note: there is no need in c file! Gcc will “connect” external c functions to your assembly program.