NASM for Linux
Total Page:16
File Type:pdf, Size:1020Kb
1 NASM for Linux Microprocessors II 2 NASM for Linux Microprocessors II NASM Package nasm package available as source or as executables Typically /usr/bin/nasm and /usr/bin/ndisasm Assembly NASM Linux requires elf format for object files ELF = Executable and Linking Format Typical header size = 330h bytes for nasm −f elf [−o <output>] <filename> Linking Linux Object files can be linked with gcc gcc [−options] <filename.o> [other_files.o] Disassembly View executable as 32-bit assembly code ndisasm −e 330h –b 32 a.out | less objdump –d a.out | less Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 3 NASM for Linux Microprocessors II 4 NASM for Linux Microprocessors II gcc Stages Example — 1 Stages of Gnu C compilation factorial2.c #include <math.h> main #include <stdio.h> sets j = 12 main() Source Translation Assembly Object Executable calls factorial 10,000,000 times Code Unit Code Code File { int times; prog.c prog.i prog.s prog.o a.out int i , j = 12; preprocess compile assemble link for (times = 0 ; times < 10000000 ; ++times){ i = factorial(j); gcc -E } gcc -S printf("%d\n",i); gcc -c } gcc int factorial(n) int n; factorial calculates n! by recursion { if (n == 0) return 1; else return n * factorial(n-1); } Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 5 NASM for Linux Microprocessors II 6 NASM for Linux Microprocessors II Example — 2 Example — 3 ~/gcc$ gcc factorial2.c Compile program as separate files produces executable a.out factorial2a.c ~/gcc$ time a.out main() { 479001600 int times; int i,j=12; for (times = 0 ; times < 10000000 ; ++times){ real 0m9.281s i = factorial(j); factorial2b.c } #include <math.h> printf("%d\n",i); user 0m8.339s #include <stdio.h> } sys 0m0.008s int factorial(n) int n; { Program a.out runs in 8.339 seconds on 300 MHz if (n == 0) Pentium II return 1; else return n * factorial(n-1); } Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 7 NASM for Linux Microprocessors II 8 NASM for Linux Microprocessors II Example — 4 Example — 5 Assembly output (AT&T gas assembly) from gcc –S factorial2a.c ~/gcc$ gcc -c factorial2a.c .file "factorial2a.c" .L3: .section .rodata subl $12, %esp produces linkable object file factorial2a.o .LC0: pushl -4(%ebp) .string "%d\n" call factorial ~/gcc$ gcc -c factorial2b.c .text addl $16, %esp .globl main movl %eax, -8(%ebp) produces linkable object file .type main, @function leal -12(%ebp), %eax factorial2b.o main: incl (%eax) pushl %ebp .L2: movl %esp, %ebp cmpl $9999999, -12(%ebp) subl $24, %esp jle .L3 ~/gcc$ gcc factorial2a.o factorial2b.o andl $-16, %esp subl $8, %esp movl $0, %eax pushl -8(%ebp) addl $15, %eax pushl $.LC0 produces executable a.out addl $15, %eax call printf shrl $4, %eax addl $16, %esp Identical to previous version sall $4, %eax leave subl %eax, %esp ret movl $12, -4(%ebp) movl $0, -12(%ebp) jmp .L2 Utility program intel2gas can convert: gas to nasm (Intel) nasm to gas nasm to gas inline assembler for C programs Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 9 NASM for Linux Microprocessors II 10 NASM for Linux Microprocessors II Output from intel2gas Example — 6 ;FILE "factorial2a.c" L3: Assembly version of factorial function written for nasm SECTION .rodata sub esp,12 .LC0: push dword [ebp-4] Uses “register variables” (no memory accesses) db '%d',10,'' call factorial Exploits advantages of Intel imul and loop instructions SECTION .text add esp,16 GLOBAL main mov [ebp-8],eax section .text2 GLOBAL main:function lea eax, [ebp-12] global factorial main: inc dword [eax] push ebp L2: factorial: mov ebp,esp cmp dword [ebp-12],9999999 push ebp sub esp,24 jle L3 and esp,-16 sub esp,8 mov ebp,esp mov eax,0 push dword [ebp-8] mov ecx,[ebp+8] add eax,15 push dword .LC0 add eax,15 call printf mov eax,1 shr eax,4 add esp,16 L1: imul ecx sal eax,4 leave loop L1 sub esp,eax ret mov dword [ebp-4],12 mov esp,ebp mov dword [ebp-12],0 pop ebp jmp L2 ret Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 11 NASM for Linux Microprocessors II 12 NASM for Linux Microprocessors II Example — 7 General NASM Template for Linux nasm -f elf -o factorial2c.o factorial2c.asm ; extern standard_library_function produces linkable object file factorial2c.o section .data ; define initialized data structures here gcc factorial2a.o factorial2c.o section .bss produces executable file a.out ; define uninitialized data structures here ~/gcc$ time a.out ; minimum allocation size is 1 dword = 32 bits 479001600 ; cannot pass BSS pointers to all system calls real 0m4.964s section .text user 0m4.287s global main ; or other line label sys 0m0.009s main: ; matching line label ; place code here ; C only version of a.out runs in 8.339 seconds on 300 MHz Pentium II mov eax, 0 ; or other exit code C + assembly version runs in 4.287 seconds on 300 MHz Pentium II ret ; return to program wrapper Speed-up of 8.339 / 4.287 ~ 2 Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 13 NASM for Linux Microprocessors II 14 NASM for Linux Microprocessors II Linux System Calls Exit NASM programs can invoke exit (terminate process) Any standard C library call EAX ← 1 Declare external library functions before data segment EBX ← exit code Push parameters onto stack in proper order INT 0x80 Call function by name Clean up stack after return Works like DOS version Any standard Linux system call MOV AH,4C Similar to DOS system calls Load parameters into EAX, EBX, ECX, EDX MOV AL,exit code INT 0x21 Call Linux kernel with INT 0x80 References: http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html http://www.lxhp.in-berlin.de/ Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 15 NASM for Linux Microprocessors II 16 NASM for Linux Microprocessors II Create File Open File creat open EAX ← 8 EAX ← 5 EBX ← pointer to ASCIIZ pathname EBX ← pointer to ASCIIZ pathname ECX ← file permissions ECX ← file access mode INT 0x80 0x00 = read only 0x01 = write only return 0x02 = read/write EAX ← integer file descriptor EDX ← file permissions INT 0x80 return EAX ← integer file descriptor Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 17 NASM for Linux Microprocessors II 18 NASM for Linux Microprocessors II Write to File Read from File write read EAX ← 4 EAX ← 3 EBX ← file descriptor EBX ← file descriptor ECX ← pointer to output buffer ECX ← pointer to input buffer EDX ← number of bytes to write EDX ← number of bytes to read INT 0x80 INT 0x80 return return EAX ← number of bytes actually written EAX ← number of bytes actually read Note Note Write to screen using stdout descriptor = 1 Read from keyboard using stdin descriptor = 0 Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 19 NASM for Linux Microprocessors II 20 NASM for Linux Microprocessors II Close File Program Example — 1 close section .data path: db "filename.txt",0 EAX ← 6 ; ASCIIZ pathname EBX ← file descriptor str1: db 'abcdefghijklmnopqrstuvwzyz',10,10 INT 0x80 ; 10 = "\n" len1 equ $-str1 ; len1 ← length of str1 str2: db 'ABCDEFGHIJKLMNOPQRSTUVWZYZ',10,10 len2 equ $-str2 ; len2 ← length of str2 buff: times 256 db 0 ; 256 zeros as buffer section .bss desc: resd 1 ; d = dword = 32-bit integer buff2: resd 1 ; minimum BSS allocation is dword ;buff: resb 256 ; cannot pass BSS pointer to ; read system call Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 21 NASM for Linux Microprocessors II 22 NASM for Linux Microprocessors II Program Example — 2 Program Example — 3 section .text get: mov eax,3 ; read from file system call global main mov ebx,0 ; file descriptor for stdin main: mov ecx,buff ; pointer to input buffer (in data segment) create: mov eax,8 ; create file system call mov edx,256 ; accept up to 265 bytes from stdin mov ebx,path ; pointer to pathname int 0x80 ; invoke Linux kernel mov ecx,0 ; no access restrictions ; int 0x80 ; invoke Linux kernel write2: mov esi,buff ; point ESI at input buffer from stdin mov [desc],eax ; save file descriptor ; w2: lodsb ; AL ← [ESI] , ESI ← ESI + 1 write: mov eax,4 ; write to file system call and eax,0x000000ff ; zero EAX except AL mov ebx,[desc] ; file descriptor cmp al,0 ; if AL = 0 then stop writing mov ecx,str1 ; pointer to string 1 je close mov edx,len1 ; number of bytes to write mov [buff2],eax ; move EAX to memory at buff2 (BSS) int 0x80 ; invoke Linux kernel mov eax,4 ; write to file system call ; mov ebx,[desc] ; file descriptor mov eax,4 ; write to file system call mov ecx,buff2 ; pointer to buffer mov ebx,[desc] ; file descriptor mov edx,1 ; number of bytes to write mov ecx,str2 ; pointer to string 2 int 0x80 ; invoke Linux kernel mov edx,len2 ; number of bytes to write jmp w2 ; continue int 0x80 ; invoke Linux kernel Fall 2007 Hadassah College Dr. Martin Land Fall 2007 Hadassah College Dr. Martin Land 23 NASM for Linux Microprocessors II 24 NASM for Linux Microprocessors II Program Example — 4 Program Example — 5 close: mov eax,6 ~/nasm/programs_linux$ nasm −f elf create.asm mov ebx,[desc] ~/nasm/programs_linux$ gcc create.o int 0x80 ~/nasm/programs_linux$ a.out ; I am writing this sentence.