.text
.globl _start
_start:
pushl $message_l
pushl $message
pushl $1
movl $4,%eax
pushl %eax
syscall
addl $16,%esp
xorl %eax,%eax
pushl %eax
incl %eax
pushl %eax
syscall
hlt
.data
message:
.string "HW!\n"
message_l = .-message-1
Компиляция:
as -o test.o test.s && ld -s test.o && ./a.out
Размер: 384 байта
Трассировка:
$ truss ./a.out
execve("./a.out", 0x08047AE4, 0x08047AEC) argc = 1
HW!
write(1, " H W !\n", 4) = 4
_exit(0)
$
Для сравнения программа на С:
#include <unistd.h>
int main(int agrc, char** agrv){
write(1,"HW!\n",4);
return 0;
}
gcc -O3 ggg.c
Размер 8128 байт
Формируемый ассемблерный код (gcc -S -O3 ggg.c )
.file "ggg.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "HW!\n"
.text
.p2align 2,,3
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
subl $20, %esp
pushl $4
pushl $.LC0
pushl $1
call write
xorl %eax, %eax
leave
ret
.size main, .-main
Трассировка:
$ truss ./a.out
execve("a.out", 0x08047A7C, 0x08047A84) argc = 1
sysconfig(_CONFIG_PAGESIZE) = 4096
mmap(0x00000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFEFB0000
mmap(0x00000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFEFA0000
memcntl(0xFEFBE000, 27724, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0) = 0xFEF90000
memcntl(0x08050000, 2580, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
resolvepath("/usr/lib/ld.so.1", "/lib/ld.so.1", 1023) = 12
getcwd("/data/compilation/asm", 1017) = 0
resolvepath("/data/compilation/asm/a.out", "/data/compilation/asm/a.out", 1023) = 27
stat64("/data/compilation/asm/a.out", 0x08047720) = 0
open("/var/ld/ld.config", O_RDONLY) Err#2 ENOENT
stat64("/usr/ccs/lib/libc.so.1", 0x08046F20) Err#2 ENOENT
stat64("/lib/libc.so.1", 0x08046F20) = 0
resolvepath("/lib/libc.so.1", "/lib/libc.so.1", 1023) = 14
open("/lib/libc.so.1", O_RDONLY) = 3
mmapobj(3, 0x00020000, 0xFEF904D0, 0x08046F8C, 0x00000000) = 0
close(3) = 0
memcntl(0xFEE30000, 188400, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
mmap(0x00010000, 24576, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFEE20000
getcontext(0x08047580)
getrlimit(RLIMIT_STACK, 0x08047578) = 0
getpid() = 1061 [1060]
lwp_private(0, 1, 0xFEE22A00) = 0x000001C3
setustack(0xFEE22A60)
sysi86(SI86FPSTART, 0xFEF8700C, 0x0000133F, 0x00001F80) = 0x00000001
HW!
write(1, " H W !\n", 4) = 4
_exit(0)
Улучшенная программа на С:
$ cat ggg_asm.h
static int inline write_asm(int fildes, const void *buf, int nbyte){
asm("pushl %0"::"r"(nbyte));
asm("pushl %0"::"r"(buf));
asm("pushl %0"::"r"(fildes));
asm("movl $4,%eax\n\t"
"pushl %eax\n\t"
"syscall\n\t"
"addl $16,%esp");
return 0;
}
static void inline exit_asm(int rel_value){
asm("pushl %0"::"r"(rel_value));
asm("movl $1,%eax\n\t"
"pushl %eax\n\t"
"syscall\n\t"
"addl $8,%esp");
}
$ cat ggg_asm.c
#include <ggg_asm.h>
void _start(){
write_asm(1,"HW!\n",4);
exit_asm(0);
}
Компиляция: gcc -fno-ident -I. -O3 -c -o ggg_asm.o ggg_asm.c && ld -s ggg_asm.o
Размер 444 байт
Формируемый ассемблерный код
.file "ggg_asm.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "HW!\n"
.text
.p2align 2,,3
.globl _start
.type _start, @function
_start:
movl $1, %ecx
movl $.LC0, %edx
movl $4, %eax
/APP
pushl %eax
pushl %edx
pushl %ecx
movl $4,%eax
pushl %eax
syscall
addl $16,%esp
/NO_APP
xorb %al, %al
/APP
pushl %eax
movl $1,%eax
pushl %eax
syscall
addl $8,%esp
/NO_APP
ret
.size _start, .-_start
Трассировка:
$ truss ./a.out
execve("./a.out", 0x08047ABC, 0x08047AC4) argc = 1
HW!
write(1, " H W !\n", 4) = 4
_exit(0)