> >1. How can I use Assembler under Linux ? The topic is a bit large. Writting and compiling assembler under Linux ============================================ 1. How to compile. Write an assember file with the extension .s. Them compile it with gcc as if it were C source. gcc will invoke the assember program (/usr/bin/as) that will generate an object file. 2. Assembler syntax. The assember syntax under Linux is very different from Intel MS-DOS. The syntax of an instruction is something like: movw %bx, %ax # ax = bx "movw" means move operand of size word (in unambiguos cases like this you could use mov). Then you type the source operand and then the destination. The order is the opposite of Intel/MS-DOS syntax. Watch the "%" before a register operand. Another example: mov $10, %eax means put the value 10 in the register EAX. Note the $ in fron of a constant. Any Intel assembler program should have a code segment and a data segment. The code segment is called "text" in Unix. Segments are usually called "sections". 3. Typical hello world program Let's write the typical "Hello world" program. .section .rodata hello: .string "Hello world\n" .text .align 16 .globl _start _start: mov $4,%eax # 4 is the number of the write system call mov $1,%ebx # 1 the standard output mov $hello, %ecx # $hello points to the hello world string mov $12, %edx # 12 is the length of the string int $0x80 # Perform the system call write(1, $hello, 12) mov $1, %eax # 1 is the number of the exit system call xor %ebx, %ebx # 0 is the return value of the program int $0x80 # Perform the system call exit(0) Write it as kk.s. Assemble it: "as -o kk.o kk.s". Link it with "ld -o kk kk.o". Now you should have an executable file ./kk. Run it typing ./kk. You should see "Hello world". (I tested before sending it, so it should work. I have a Linux ELF system). The int $0x80 performs a system call. Below I will expain a little more about it. 4. The Linux system call interface To perform a system call you have to do these tasks: a) Put the system call number in the register eax The system call number is a number used by the operating system to identify you system call and differenciate it from others. You can see what system calls are available in Linux browsing the section 2 of the manual (ls /usr/man/man2). Viewing the file /usr/include/asm/unistd.h you can see the the number of each system call. If you want to view what system calls are available in a particular Linux kernel version, view the file linux/arch/i386/entry.S, and look for the string "sys_". You will find there the kernel table of system calls. b) Put the arguments in the registers %ebx, %ecx, %edx, %esi, %edi in that order. You do not need to put any values in the registers that you do not use. The mmap system call uses 6 arguments and is a bit special. Arguments are placed in a memory buffer. Then the buffer pointer is passed in the register %ebx. 5. More info Check the GNU assembler info pages. On my Redhat system, I can find them typing info -f as. Choose the menu entry "Machine Dependecies", then choose "i386-Dependent", and them "i386-Syntax". You will find a description of the assember syntax of the GNU assembler, compared with the syntax of Intel assembler. 6. Find out yourself Check gcc output. If you write a very simple C program, and you compile it with the flag -S, gcc will generate a .s file with the assembler output. This is useful to give you an idea of how an assember program looks. The output of the program: #include main() { write(1, "Hola", 4); } is: .file "kk.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "Hola" .text .align 16 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp pushl $4 pushl $.LC0 pushl $1 call write addl $12,%esp .L2: movl %ebp,%esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.7.2" The directives .ident, .size and .type are useful for helping the debugger. Find out more with gdb. Type: gdb /usr/lib/libc.so inside gdb type disassemble write You will see an assembler listing of the write function. Directives start with a dot. You might want to check the Linux kernel source. Some files (with .S extension) are assembler code (the .S extension means that first they are preprocessed by the C preprocessor; this allows to use C macros inside assembler source). Consider using embedder assembler in C source. Check gcc documentation: info -f gcc. Choose the menu entry "C Extensions" followed by "Extended Asm". The Linux kernel offers you some examples of assembler included in C. For example, the low level string routines /usr/include/asm/string.h (or even /usr/include/asm/string-486.h). There you can learn how to use the internal GCC function __builtin_constant_p(var) that returns true if the expresion var is a constant, thus allowing to write very tunned assembler code.