Example:
Code:
# init.S
.code64
.section .text
.globl _start
.extern main
_start:
movl (%rsp),%edi # int argc;
lea 8(%rsp),%rsi # char **argv;
call main
# exit(main(argc, argv));
movl %eax,%edi
movl $60,%eax
syscall
Code:
/* main.c */
#include <stddef.h>
static void printstr( char * );
int main( int argc, char *argv[] )
{
if (argc != 2)
return 1;
printstr( *++argv );
printstr( "\n" );
return 0;
}
void printstr( char *s )
{
size_t count = 0;
char *p;
p = s;
while (*p++) count++;
__asm__ __volatile__ (
"movl $1,%%eax\n\t"
"movl %%eax,%%edi\n\t"
"syscall" : :
"S" (s), // string ptr.
"d" (count) // string size.
: "rax", "rdi"
);
}
Code:
# Makefile
main: main.o init.o
ld -nostdlib -o $@ $^
main.o: main.c
cc -O2 -ffreestanding -c -o $@ $<
init.o: init.S
as -o $@ $<
Compiling, linking and viewing the final file:
Code:
$ make
cc -O2 -ffreestanding -c -o main.o main.c
as -o init.o init.S
ld -nostdlib -o main main.o init.o
$ ./main fred
fred
$ objdump -dM intel main
Disassembly of section .text:
00000000004000b0 <main>:
4000b0: 83 ff 02 cmp edi,0x2
4000b3: b8 01 00 00 00 mov eax,0x1
4000b8: 74 01 je 4000bb <main+0xb>
4000ba: c3 ret
4000bb: 48 8b 76 08 mov rsi,QWORD PTR [rsi+0x8]
4000bf: 31 d2 xor edx,edx
4000c1: 80 3e 00 cmp BYTE PTR [rsi],0x0
4000c4: 74 14 je 4000da <main+0x2a>
4000c6: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
4000cd: 00 00 00
4000d0: 48 83 c2 01 add rdx,0x1
4000d4: 80 3c 16 00 cmp BYTE PTR [rsi+rdx*1],0x0
4000d8: 75 f6 jne 4000d0 <main+0x20>
4000da: b8 01 00 00 00 mov eax,0x1
4000df: 89 c7 mov edi,eax
4000e1: 0f 05 syscall
4000e3: 48 8d 35 27 00 00 00 lea rsi,[rip+0x27] # 400111 <_start+0x16>
4000ea: ba 01 00 00 00 mov edx,0x1
4000ef: b8 01 00 00 00 mov eax,0x1
4000f4: 89 c7 mov edi,eax
4000f6: 0f 05 syscall
4000f8: 31 c0 xor eax,eax
4000fa: c3 ret
00000000004000fb <_start>:
4000fb: 8b 3c 24 mov edi,DWORD PTR [rsp]
4000fe: 48 8d 74 24 08 lea rsi,[rsp+0x8]
400103: e8 a8 ff ff ff call 4000b0 <main>
400108: 89 c7 mov edi,eax
40010a: b8 3c 00 00 00 mov eax,0x3c
40010f: 0f 05 syscall