$ cat > hello.S <<'EOF'
        .data
.Lhello:
        .ascii "Hello, world\n"
        .text
        .global _start
_start:
        movl    $1, %ebx
        leal    .Lhello, %ecx
        movl    $13, %edx
        movl    $4, %eax
        int     $0x80
        movl    $1, %eax
        xorl    %ebx, %ebx
        int     $0x80
EOF
$ gcc -m32 hello.S -nostdlib -o hello
$ ./hello
Hello, world
$
С голым машинным кодом будет сложнее, т.к. нужно будет согласовать адреса закодированные в нём с тем, что будет прописано в заголовках ELF. Можно сделать примерно такой исходник:
.text
        .global _start
_start:
.incbin "code"
в файл code поместить голый машинный код. Компилировать как в первом случае.
Как вариант можно дамп вставить прямо в ассемблер:
.text
        .global _start
_start:
        .byte 0xbb, 0x01, 0x00, 0x00, 0x00, 0x8d, 0x0d, 0xb8, 
        .byte 0x80, 0x04, 0x08, 0xba, 0x0d, 0x00, 0x00, 0x00, 
        .byte 0xb8, 0x04, 0x00, 0x00, 0x00, 0xcd, 0x80, 0xb8, 
        .byte 0x01, 0x00, 0x00, 0x00, 0x31, 0xdb, 0xcd, 0x80, 
        .byte 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 
        .byte 0x6f, 0x72, 0x6c, 0x64, 0x0a
Можно зайти с другой стороны и научить линукс выполнять голые бинарники. См. 
https://www.kernel.org/doc/Documentation/binfmt_mi...