Practical Session 5
Practical Session 5. GNU Linker. Links object files together Used as the last step in the compilation We will use ld to link together compiled assembly without using c. Usage: nasm –f elf myprog.s –o myprog.o ld -m elf_i386 myprog.o –o myprog.bin. Command Line Arguments in NASM.
Practical Session 5
E N D
Presentation Transcript
GNU Linker • Links object files together • Used as the last step in the compilation • We will use ld to link together compiled assembly without using c. • Usage: • nasm –f elf myprog.s –o myprog.o • ld -m elf_i386 myprog.o –o myprog.bin
Command-line arguments In Linux, we receive command-line arguments on the stack as execution starts:- The first argument; 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])
Caller side • The caller pushes the function's parameters on the stack, one after another, in reverse order. • The caller executes a CALL instruction to pass control to the callee. This CALL is either near or far depending on the memory model. • The address of the next instruction is pushed onto the stack as the return address.
Function _start Stack structure dword EBP argc dword Ret add (offset) argv[0] argv[1] Param #1 Param #2 argv[2] … …
Function call example STR: DB ‘Printing two ints: %d, %d’,10,0 … MOV EAX, 15 PUSH EAX ; 3rd parameter PUSH DWORD 20 ; 2nd parameter PUSH DWORD STR ; 1st parameter CALL PRINTF ADD ESP, 12 ; 3 dwords = 12 bytes
Stack contents ; how to get parameters PUSH EBP MOV EBP, ESP MOV EAX, dword [EBP+8] ; 1st parameter MOV EBX, dword [EBP+12] ; 2nd parameter MOV ECX, dword [EBP+16] ; 3rd parameter … … dword EBP Ret add (offset) dword dword STR dword 20 15 dword
section .rodata error_string: db "Not enough arguments!",10,0 section .bss input_string_ptr: resd 1 ; Will contain the pointer to the input string output_string: resb 256 ; Will contain the actual string after copy section .text global _start _start: pop ebx ; Contains the number of arguments (Including argv[0]) cmpebx, 2 jlprint_error pop ebx ; First argument: Name of the program pop ebx ; The first argument - Our argument movdword [input_string_ptr], ebx push dword [input_string_ptr] push dwordoutput_string callcpy_string ; Copy the string to our own buffer add esp, 8 Print String
Print String push dwordoutput_string callinsert_linefeed ; Add a linefeed character (not present in the input) add esp, 4 push dwordoutput_string callmy_print ; Print the output string add esp, 4 mov ebx,0 ; Exit with return code of 0 (no error) proc_exit: mov eax,1 ; The system call for exit (sys_exit) int 80h print_error: ; This is not a function! Just a jmp destination! push error_string callmy_print add esp, 4 movebx, 1 ; Exit with return code of 1 (error) jmpproc_exit
;;;;; This function calculates the length of a string ;;;;; Parameter 1: A pointer to a string ;;;;; Return Value: Integer calc_str_len: push ebp movebp, esp push ebx push ecx movebx, dword [ebp+8] ; The input in ebx moveax, 0 ; The result will be in eax len_next_char: movcl, byte [ebx] cmpcl, 0 je len_next_char_end inc eax inc ebx jmplen_next_char len_next_char_end: pop ecx pop ebx movesp, ebp pop ebp ret calc_str_len
;;;;; This function prints an input string. Note: input string must end with 0! ;;;;; Parameter 1: A pointer to a string ;;;;; Return Value: VOID my_print: push ebp movebp, esp pushad movecx, dword [ebp+8] push ecx callcalc_str_len ; Calculate the length of the input string add esp, 4 movedx, eax moveax, 4 movebx, 1 int 80h popad movesp, ebp pop ebp ret my_print
;;;;; This function will copy a string from an input memory buffer to another ;;;;; Parameter 1: Destination Buffer (Address) ;;;;; Parameter 2: Source Buffer (Address) ;;;;; Return Value: VOID cpy_string: push ebp movebp, esp pushad movebx, dword [ebp+8] ; Pointer to Destination movecx, dword [ebp+12] ; Pointer to Source mov dl, byte[ecx] cpy_next_char: mov byte [ebx], dl cmp dl, 0 je cpy_next_char_end inc ebx inc ecx mov dl, byte[ecx] jmpcpy_next_char cpy_next_char_end: popad movesp, ebp pop ebp ret cpy_string
;;;;; This function will add a linefeed character to a string in a memory buffer ;;;;; Parameter 1: Address of memory buffer containing the string ;;;;; Return Value: VOID insert_linefeed: push ebp movebp, esp pushad movebx, dword [ebp+8] push ebx callcalc_str_len add esp,4 add ebx, eax ; Go to the end of the string mov byte [ebx], 10 ; Add linefeed inc ebx mov byte [ebx], 0 ; Add null terminal popad movesp, ebp pop ebp ret insert_linefeed
ld vs. gcc main _start This is just like C’s main(int argc, char* argv[]) argc Ret address argv[0] argc &{argv[0],arg[1],…} argv[1] argv[2] … …