This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
programming:assembly:assembly_programming [2021/03/21 06:32] nanodano [x86 on Linux] |
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. '' | There are many Assembly compilers out there. '' | ||
Line 8: | Line 9: | ||
Use interrupt '' | Use interrupt '' | ||
- | For a list of system calls in Linux, refer to [[https:// | + | For a list of system calls in Linux, |
+ | |||
+ | Here is an example of compiling with '' | ||
+ | |||
+ | <code bash> | ||
+ | nasm -f elf64 file.asm | ||
+ | # or for 32-bit | ||
+ | nasm -f elf file.asm | ||
+ | </ | ||
+ | |||
+ | If you need to link against something you can use: | ||
+ | |||
+ | <code bash> | ||
+ | ln -d -o outfile file.o | ||
+ | </ | ||
+ | |||
+ | |||
+ | 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 | ||
+ | </ | ||
+ | |||
+ | Compile and run with: | ||
+ | |||
+ | <code bash> | ||
+ | # Compile | ||
+ | nasm -f elf64 hello.asm -o hello.o | ||
+ | |||
+ | # Link | ||
+ | ld hello.o -o hello | ||
+ | |||
+ | # Run | ||
+ | ./hello | ||
</ | </ | ||
===== x86 on DOS ===== | ===== x86 on DOS ===== | ||
Line 41: | Line 72: | ||
For a list of BIOS system calls, refer to [[https:// | For a list of BIOS system calls, refer to [[https:// | ||
+ | |||
+ | ===== 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 '' | ||
+ | |||
+ | <code asm static_lib.asm> | ||
+ | ; Compile this program using | ||
+ | ; nasm -f elf64 static_lib.asm | ||
+ | ; gcc myprogram.c static_lib.o | ||
+ | ; ./a.out | ||
+ | |||
+ | SECTION .DATA | ||
+ | hello: | ||
+ | helloLen: | ||
+ | |||
+ | SECTION .TEXT | ||
+ | GLOBAL print_hello | ||
+ | |||
+ | print_hello: | ||
+ | mov eax,4 ; ' | ||
+ | mov ebx,2 ; file descriptor 1 = STDOUT | ||
+ | mov ecx, | ||
+ | mov edx, | ||
+ | int 80h ; call the kernel | ||
+ | |||
+ | ; Terminate program | ||
+ | mov eax,1 ; ' | ||
+ | mov ebx,0 ; exit with error code 0 | ||
+ | int 80h ; call the kernel | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Create an executable ===== | ||
+ | |||
+ | By creating a '' | ||
+ | |||
+ | <code asm c_main.asm> | ||
+ | ; Because we have a reference to ' | ||
+ | ; 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: | ||
+ | helloLen: | ||
+ | |||
+ | SECTION .TEXT | ||
+ | GLOBAL main | ||
+ | |||
+ | main: | ||
+ | mov eax,4 ; ' | ||
+ | mov ebx,2 ; file descriptor 1 = STDOUT | ||
+ | mov ecx, | ||
+ | mov edx, | ||
+ | int 80h ; call the kernel | ||
+ | |||
+ | ; Terminate program | ||
+ | mov eax,1 ; ' | ||
+ | mov ebx,0 ; exit with error code 0 | ||
+ | int 80h ; call the kernel | ||
+ | </ | ||
+ | |||
+ | And compile and run with: | ||
+ | |||
+ | <code bash> | ||
+ | nasm -f elf64 c_main.asm | ||
+ | gcc c_main.o | ||
+ | ./a.out | ||
+ | </ | ||
+ | |||
+ | ===== Call Assembly functions from C ===== | ||
+ | |||
+ | <code c example.c> | ||
+ | /* example.c */ | ||
+ | /* Compile and run with `gcc example.c say_hi.o -o hello` */ | ||
+ | #include < | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | extern say_hi(); | ||
+ | say_hi(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Next, compile and link the C program with gcc. Do that with: | ||
+ | |||
+ | <code bash> | ||
+ | gcc example.c say_hi.o -o hello | ||
+ | </ | ||
+ | |||
+ | You can then run the '' | ||
+ | |||
+ | <code bash> | ||
+ | ./hello | ||
+ | </ | ||
+ | |||
+ | ===== 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", | ||
+ | fmt: db " | ||
+ | |||
+ | 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 | ||
+ | </ | ||
+ | |||
+ | Compile and run that with: | ||
+ | |||
+ | <code bash> | ||
+ | nasm printf.asm -f elf64 -o printf.o | ||
+ | gcc printf.o | ||
+ | ./a.out | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||