If someone is interested, here is the source code for a small Linux filter, written in AT&T syntax.


#File: lower2upper.s
#Build the running application at the command line with:
#
# as -o lower2upper.o lower2upper.s
# ld -o lower2upper lower2upper.o
#
# With:
#
# ./ lower2upper lower2upper.s upper.new
#
# at the command line, you'll find upper.new, an uppercase version of your original source file.

.globl _start

#Constants

.equ SYS_EXIT,1
.equ SYS_READ,3
.equ SYS_WRITE,4
.equ SYS_OPEN,5
.equ SYS_CLOSE,6
.equ LINUX_SYSCALL,0x80
.equ O_RDONLY,0
.equ O_CREAT_WRONLY_TRUNC,03101
.equ STDIN,0
.equ STDOUT,1
.equ STDERR,2
.equ END_OF_FILE,0
.equ NUMBER_ARGUMENTS,2

.section .bss

.equ BUFFER_SIZE,500
.lcomm BUFFER_DATA,BUFFER_SIZE

.section .text

#STACK POSITIONS

.equ ST_SIZE_RESERVE,8
.equ ST_FD_IN,-4
.equ ST_FD_OUT,-8
.equ ST_ARGC,0 #Number of arguments
.equ ST_ARGV_0,4 #program name
.equ ST_ARGV_1,8 #Input file name
.equ ST_ARGV_2,12 #Output file name

_start:

movl %esp,%ebp #save stack pointer
subl $ST_SIZE_RESERVE,%esp #space for file descriptors

#open input file

movl $SYS_OPEN,%eax #eax = open syscall
movl ST_ARGV_1(%ebp),%ebx #ebx = input file handle
movl $O_RDONLY,%ecx #ecx = read only flag
movl $0666,%edx #doesn’t really matter for reading
int $LINUX_SYSCALL #transfer to kernel
movl %eax,ST_FD_IN(%ebp) #save file descriptor

#open output file

movl $SYS_OPEN,%eax #eax = open syscall
movl ST_ARGV_2(%ebp),%ebx #ebx = output file handle
movl $O_CREAT_WRONLY_TRUNC,%ecx
movl $0666,%edx #create new file
int $LINUX_SYSCALL #transfer to kernel
movl %eax,ST_FD_OUT(%ebp) #store file descriptor

read_loop_begin:

movl $SYS_READ,%eax #read block from input file
movl ST_FD_IN(%ebp),%ebx #ebx = input file descriptor
movl $BUFFER_DATA,%ecx #ecx = read position
movl $BUFFER_SIZE,%edx #edx = buffer size
int $LINUX_SYSCALL #transfer to kernel
cmpl $END_OF_FILE,%eax #end of file reached?
jle end_loop #yes: jump

continue_read_loop:

#no: convert the block to upper case

pushl $BUFFER_DATA #buffer location
pushl %eax #buffer size
call convert_to_upper
popl %eax #restore buffer size
addl $4,%esp #adjust stack

#write block to output file

movl %eax,%edx #edx = buffer size
movl $SYS_WRITE,%eax
movl ST_FD_OUT(%ebp),%ebx #ebx = file descriptor
movl $BUFFER_DATA,%ecx #ecx = write position
int $LINUX_SYSCALL #transfer to kernel
jmp read_loop_begin #continue read/write loop

end_loop:

#close output file

movl $SYS_CLOSE,%eax
movl ST_FD_OUT(%ebp),%ebx
int $LINUX_SYSCALL #transfer to kernel

#close input file

movl $SYS_CLOSE,%eax
movl ST_FD_IN(%ebp),%ebx
int $LINUX_SYSCALL #transfer to kernel

#terminate

addl $ST_SIZE_RESERVE,%esp
movl $SYS_EXIT,%eax
movl $0,%ebx
int $LINUX_SYSCALL #transfer to kernel


#convert_to_upper
#Task: Convert a block to upper case.
#Input:   = buffer length
# = buffer
#Output: Function overwrites the current buffer with upper-cassified version.

#constants

.equ LOWERCASE_A,'a' #lower search boundary
.equ LOWERCASE_Z,'z' #upper search boundary
.equ UPPER_CONVERSION,'A' - 'a'
.equ ST_BUFFER_LEN,8 #buffer length
.equ ST_BUFFER,12 #actual buffer

convert_to_upper:

pushl %ebp
movl %esp,%ebp
movl ST_BUFFER(%ebp),%eax #eax = actual buffer
movl ST_BUFFER_LEN(%ebp),%ebx#ebx = buffer length
movl $0,%edi #edi = current buffer offset
cmpl $0,%ebx #buffer length = 0?
je end_convert_loop #yes: jump

convert_loop:

movb (%eax,%edi,1),%cl #no: get current byte

#go to the next byte unless it is between 'a' and 'z'

cmpb $LOWERCASE_A,%cl
jl next_byte
cmpb $LOWERCASE_Z,%cl
jg next_byte

#otherwise convert the byte to uppercase

addb $UPPER_CONVERSION,%cl
movb %cl,(%eax,%edi,1) #store it back

next_byte:

incl %edi #next byte
cmpl %edi,%ebx #end reached?
jne convert_loop #no: play it again

end_convert_loop:

popl %ebp #yes: back to caller
ret


It's only an easy example, to show the principle by using as and ld for building a complete assembly language application. Nothing special. The program doesn't make any error detection for the system calls, but should run correct under x86 based 32 bit Linux.

Gunther


Posted on 2010-08-19 18:02:16 by Gunther