next up previous
Next: Conclusion Up: Programming in Assembly Previous: Inline Assembly Statements

Programming in Assembly Language

If we need to pass five arguments in a system call, the inline assembly statement won't work with PIC since x86 doesn't have enough registers to go around. We need to program in assembly language directly.

The normal assembly language code for

syscall (int syscall_number, ...);

looks like:

        .file "syscall.S"
        .text
        .global syscall
        .global errno
        .align 16
syscall:
        pushl %ebp
        movl %esp,%ebp
        pushl %edi
        pushl %esi
        pushl %ebx
        movl 8(%ebp),%eax
        movl 12(%ebp),%ebx
        movl 16(%ebp),%ecx
        movl 20(%ebp),%edx
        movl 24(%ebp),%esi
        movl 28(%ebp),%edi
        int $0x80
        test %eax,%eax
        jge .LLexit
        negl %eax
        movl %eax,errno
        movl $-1,%eax
.LLexit:
        popl %ebx
        popl %esi
        popl %edi
        movl %ebp,%esp
        popl %ebp
        ret
        .type syscall,@function
.L_syscall_end:
        .size syscall,.L_syscall_end - syscall

Under PIC, we have to access any global variable via the global offset table in addition to preserving the base register ebx. The modified code is:

        .file "syscall.S"
        .text
        .global syscall
        .global errno
        .align 16
syscall:
        pushl %ebp
        movl %esp,%ebp
        pushl %edi
        pushl %esi
        pushl %ebx
        call .LL4
.LL4:
        popl %ebx
        addl $_GLOBAL_OFFSET_TABLE_+[.- .LL4],%ebx
        pushl %ebx
        movl 8(%ebp),%eax
        movl 12(%ebp),%ebx
        movl 16(%ebp),%ecx
        movl 20(%ebp),%edx
        movl 24(%ebp),%esi
        movl 28(%ebp),%edi
        int $0x80
        popl %ebx
        movl %eax,%edx
        test %edx,%edx
        jge .LLexit
        negl %edx
        movl errno@GOT(%ebx),%eax
        movl %edx,(%eax)
        movl $-1,%eax
.LLexit:
        popl %ebx
        popl %esi
        popl %edi
        movl %ebp,%esp
        popl %ebp
        ret
        .type syscall,@function
.L_syscall_end:
        .size syscall,.L_syscall_end - syscall

Finally, if one wants to program in assembly language for PIC and one is not sure how to do it, one can always write the C code and then do

# gcc -O -fPIC -S foo.c

This will tell gcc to generate the assembly output, foo.s. One can take a look at and modify it according to one's needs.



J.H.M.Dassen
Tue Aug 1 14:18:10 MDT 1995