Background knowledge basically explained clearly, below we actually write a small example to look at. The functionality of the code is simple, displaying a line of text, and then exiting. We used the write and exit calls in Syscall to look up the previous call numbers and parameters, and we made a preliminary summary as follows:
Write (that is, sys_write) call number 1, 3 parameters to be passed
unsignedint fdconstchar *bufsize_t count
Exit (SYS_EXIT) Call number 60, just pass an error code
int error_code
A value of 0 indicates that the program executed successfully.
Since there are only 3 parameters for the above two calls, we will only use 3 registers Rdi,rsi and RDX in turn.
The actual code is as follows:
section .text;if use ldglobal _start;if use gcc;global main_start:;main mov rax,1 ;write NO mov rdx,1 ;fd mov rsi,msg ofstring ofstring syscall mov rax,60 ;exit NO mov rdi,0 ;error_code syscall "Hello World!",0xa msg_len:equ $-msg
The compile connection command is as follows:
nasm -f elf64 p.sld -o p p.o
If this is the Mac OS X system, the command is as follows:
nasm -f macho64 p.sld -o p p.o
Because the title of Benbow is a compilation under Linux, please refer to this cat's other blog post [Mac OS X64 bit and 32-bit assembler system call] under Mac OS X.
If you want to generate 32-bit code, at compile time to change the elf64 to ELF32, but I said before: 32-bit and 64-bit assembly structure changes, light change this is no way to run successfully.
As expected code runs output line: Hello world! And the program returns with the echo $? Look, it should be 0.
This example is very simple, take a look at a slightly more complex call: Mmap, the call has 6 parameters, we summarize the following:
The mmap (SYS_MMAP) system call number is 9 and the parameters are:
unsignedlong addrunsignedlong lenunsignedlong protunsignedlong flagsunsignedlong fdunsignedlong offset
The first parameter is the address we need to map to, we pass 0 here, which means we don't care where the map is, the second parameter is the size of the mapping space, the third parameter represents the protection of the map area, there are many kinds, we only make it readable and writable, so we only use the combination of 2:
prot_write| Prot_read
The fourth parameter is some of the features of the map area, and there are many combinations. Only use map_shared| here. Map_anonymous, which indicates the establishment of an anonymous mapping, ignores parameter fd, so no file is set.
The fifth parameter is FD, which is said to be ignored, so we pass-1; the last parameter is the offset of the map, and we pass 0.
If the call succeeds in returning the start address of the mapped area's memory, it returns map_failed (-1), the reason for the error is in errno, and we can use Strerror (errno) to see what it means. But this function is in the C library, here we piggyback to use a bit.
Referring to Mmap we have to mention Munmap, guess what the call means:
The Munmap (SYS_MUNMAP) call number is 11 and 2 parameters are passed:
longlen
Linux under 64-bit assembly system call (3)