User Tools

Site Tools


programming:assembly:assembly_programming

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
programming:assembly:assembly_programming [2021/03/21 06:38]
nanodano
programming:assembly:assembly_programming [2021/03/22 02:22] (current)
nanodano ↷ Page name changed from programming:assembly:home to programming:assembly:assembly_programming
Line 3: Line 3:
 ====== Assembly Programming ====== ====== Assembly Programming ======
  
 +Assembly is about as close as you can get to machine code. 
 There are many Assembly compilers out there. ''nasm'' is one compiler that is available across platforms and can be used to program x86 processors. There are many Assembly compilers out there. ''nasm'' is one compiler that is available across platforms and can be used to program x86 processors.
  
Line 8: Line 9:
  
 Use interrupt ''0x80'' to make Linux system calls like reading and writing to file descriptors and sockets. Use interrupt ''0x80'' to make Linux system calls like reading and writing to file descriptors and sockets.
-For a list of system calls in Linux, refer to [[https://man7.org/linux/man-pages/man2/syscalls.2.html]]+For a list of system calls in Linux, run ''man syscalls'' or refer to an online man page like [[https://man7.org/linux/man-pages/man2/syscalls.2.html]]. To get the actual number, try to find the ''unistd.h'' file. For example, in Debian, ''/usr/include/asm-generic/unistd.h'' has all of the statements that define the syscall numbers (''NR''). Or, refer to the source code of Linux (pick the right branch) [[https://github.com/torvalds/linux/blob/v4.17/arch/x86/entry/syscalls/syscall_64.tbl]] and [[https://github.com/torvalds/linux/blob/v4.17/arch/x86/entry/syscalls/syscall_32.tbl]]. 
 + 
 +Here is an example of compiling with ''nasm'': 
 + 
 +<code bash> 
 +nasm -f elf64 file.asm  
 +# or for 32-bit 
 +nasm -f elf file.asm 
 +</code> 
 + 
 +If you need to link against something you can use: 
 + 
 +<code bash> 
 +ln -d -o outfile file.o 
 +</code> 
 + 
 + 
 +Here is a Hello World example:
  
 <code asm hello.asm> <code asm hello.asm>
Line 30: Line 48:
  int 80h              ; call the kernel  int 80h              ; call the kernel
  
 +</code>
 +
 +Compile and run with:
 +
 +<code bash>
 +# Compile
 +nasm -f elf64 hello.asm -o hello.o
 +
 +# Link
 +ld hello.o -o hello
 +
 +# Run
 +./hello
 </code> </code>
 ===== x86 on DOS ===== ===== x86 on DOS =====
Line 42: Line 73:
 For a list of BIOS system calls, refer to [[https://en.wikipedia.org/wiki/BIOS_interrupt_call]]. For a list of BIOS system calls, refer to [[https://en.wikipedia.org/wiki/BIOS_interrupt_call]].
  
-===== Writing a library =====+===== Create a library ===== 
 + 
 +You can write and compile libraries that can be linked against by other programs.  
 + 
 +This example shows how to create a function called ''print_hello()'' that can be used from other Assembly or C programs.
  
 <code asm static_lib.asm> <code asm static_lib.asm>
Line 69: Line 104:
  int 80h              ; call the kernel  int 80h              ; call the kernel
 </code> </code>
 +
 +
 +===== Create an executable =====
 +
 +By creating a ''main()'' function, we can make an executable instead of a library.
 +
 +<code asm c_main.asm>
 +; Because we have a reference to 'main'
 +; we can compile with nasm to create the
 +; .o object file, and then compile that with
 +; gcc. Example
 +; nasm -f elf64 c_main.asm 
 +; gcc c_main.o
 +; ./a.out
 +
 +SECTION .DATA
 + hello:     db 'Hello world!',10
 + helloLen:  equ $-hello
 +
 +SECTION .TEXT
 + GLOBAL main
 +
 +main:
 + mov eax,4            ; 'write' system call = 4
 + mov ebx,2            ; file descriptor 1 = STDOUT
 + mov ecx,hello        ; string to write
 + mov edx,helloLen     ; length of string to write
 + int 80h              ; call the kernel
 +
 + ; Terminate program
 + mov eax,1            ; 'exit' system call
 + mov ebx,0            ; exit with error code 0
 + int 80h              ; call the kernel
 +</code>
 +
 +And compile and run with:
 +
 +<code bash>
 +nasm -f elf64 c_main.asm 
 +gcc c_main.o
 +./a.out
 +</code>
 +
 +===== Call Assembly functions from C =====
 +
 +<code c example.c>
 +/* example.c */
 +/* Compile and run with `gcc example.c say_hi.o -o hello` */
 +#include <stdio.h>
 +
 +int main(int argc, char *argv[]) {
 + extern say_hi();
 + say_hi();
 +}
 +</code>
 +
 +Next, compile and link the C program with gcc. Do that with:
 +
 +<code bash>
 +gcc example.c say_hi.o -o hello
 +</code>
 +
 +You can then run the ''hello'' program that was just created.
 +
 +<code bash>
 +./hello
 +</code>
 +
 +===== Call C function from Assembly =====
 +
 +
 +You can call C functions from Assembly as well. This example calls printf(). In the main function, we push and pop the stack and put our operations in between. We move all the parameters in to the appropriate registers, and then we call the function.
 +
 +<code asm printf.asm>
 +; printf.asm
 +; Define printf as an external function
 +extern printf
 +
 +SECTION .DATA
 +    msg: db "Hello world", 0 ; Zero is Null terminator 
 +    fmt:    db "%s", 10, 0 ; printf format string follow by a newline(10) and a null terminator(0), "\n",'0'
 +
 +SECTION .TEXT
 +    global main
 +    
 +main:
 +    push rbp ; Push stack
 +
 +    ; Set up parameters and call the C function
 +    mov rdi,fmt
 +    mov rsi,msg
 +    mov rax,0
 +    call printf
 +
 +    pop rbp ; Pop stack
 +
 +    mov rax,0 ; Exit code 0
 +    ret ; Return
 +</code>
 +
 +Compile and run that with:
 +
 +<code bash>
 +nasm printf.asm -f elf64 -o printf.o
 +gcc printf.o
 +./a.out
 +</code>
 +
 +
 +
 +
 +
programming/assembly/assembly_programming.1616308711.txt.gz · Last modified: 2021/03/21 06:38 by nanodano