# For i386 Linux.  You'll have to run this through cpp and gas;
# easiest way is to put it in a file whose name ends in .S and say
# gcc -m32 -nostdlib -static -o printstring printstring.S
#include <asm/unistd.h>
        .section .rodata
mystr:  .asciz "ABCDE is a string"
        .data
byte:   .byte 0
        
        .text
        
        .globl _start
_start: mov $mystr, %eax
        call printchars
        mov $'\n, %eax
        call printchar
        mov $__NR_exit, %eax
        mov $0, %ebx
        int $0x80
        
printchars:                     # args:  %eax points to string
        xor %ebx, %ebx
loop:   mov (%eax), %bl
        inc %eax
        
        push %eax
        push %ebx
        movzbl %bl, %eax
        call printnumspc
        pop %ebx
        pop %eax

        and %ebx, %ebx          # nul-terminated string
        jnz loop
        ret
printnumspc:                    # args: %eax is number to print
        call printnum           # number must be nonnegative
        mov $32, %eax           # space char
        jmp printchar           # tail-call
printnum:                       # args: %eax is number to print
        mov $10, %ebx
        mov $'0, %ecx
        and %eax, %eax
        jnz printnonzero
        mov $'0, %eax
        jmp printchar           # tail-call
        
printnonzero:                   # args: %eax is number to print
                                # number must be nonnegative
        xor %edx, %edx          # %ebx is base (nonclobbered)
        idiv %ebx               # %ecx is zero digit
                                # (nonclobbered)
        and %eax, %eax
        jz done
        
        push %edx
        call printnonzero
        pop %edx
        
done:   add %ecx, %edx
        
        push %eax
        push %ebx
        push %ecx
        mov %edx, %eax
        call printchar
        pop %ecx
        pop %ebx
        pop %eax
        ret
        
printchar:                      # args: %al is char to print
        mov %al, byte
        mov $__NR_write, %eax
        mov $1, %ebx            # stdout
        mov $byte, %ecx
        mov $1, %edx            # length
        int $0x80
        ret

Reply via email to