The first file is the library file that we actually wrote, and the second one is the test program that we wrote the library for. It's not a complete I/O library, so it's more like a demo or a "this is how it works" example.
Unfortunately the comments are in Swedish.
I'll fix that if I get time.
library.s
Code: Select all
#include <stdlib>
.data
oBuff: .skip 80 /*Output buffert*/
iBuff: .skip 80 /*Input buffert*/
intBuff: .skip 80 /*Int buffert*/
iPos: .long 0
oPos: .long 0
intPos: .long 0
/*
Register:
eax = returvärden/kan användas
ebx = kan användas
ecx = kan användas
*/
.text
.globl outimage
.globl putchar
.globl gettext
.globl inimage
.globl getinpos
.globl setinpos
.globl puttext
.globl setoutpos
.globl getoutpos
.globl putint
.globl getint
/*Här börjar inimage och dess subrutiner*/
inimage:
enter $0,$0
pushl stdin
pushl $80
pushl $iBuff
call fgets
movl $0, iPos
leave
ret
/*Läser in en ny rad med hjälp av fgets och lägger i in-bufferten, sätter pos till 0*/
getint:
/*Returnerar ett heltal till %eax, gå igenom en sträng (inbufferten).
Fortsätt tills man får ett tecken som inte är tillåtet.
kan inledas med en blank, - eller +.
Om man står vid slutet av buffert så görs inimage automatiskt
Om tillåtna strängen har längden 0 så görs automatiskt en inimage*/
enter $0,$0
call getchar
movl $1, %ecx
movl $1, %ebx
wsloop:
cmpb $' ', %al
jne prefixchars
call getchar
jmp wsloop
prefixchars:
cmpb $'-', %al
je piam
cmpb $'+', %al
je nchar
cmpb $'0', %al
jl fail
cmpb $'9', %al
jg fail
jmp mDigit
piam:
movl $-1, %ecx
nchar:
call getchar
mDigit:
sub $'0', %al
imul %eax, %ebx
digitloop:
call getchar
cmpb $'0', %al
jl retur
cmpb $'9', %al
jg retur
sub $'0', %al
imul $10, %ebx
addl %eax, %ebx
jmp digitloop
retur:
imul %ecx, %ebx
movl %ebx, %eax
leave
ret
fail:
movl $0, %eax
sub $1, iPos
leave
ret
gettext:
enter $0,$0
movl iPos, %ebx
movl 8(%ebp),%ecx
movl 12(%ebp),%edx
addl $iBuff,%ebx
movl $0, %eax
jonasLoop:
cmpl $0x0, (%ebx)
je endJonas
cmpl $0xA, (%ebx)
je endJonas
cmpl %eax, %edx
je endJonas
cmpl $0x4F, %eax
je endJonas
pushl %eax
movb (%ebx), %al
movb %al, (%ecx)
popl %eax
addl $1, %ebx
addl $1, %ecx
addl $1, %eax
cmpl %eax, %edx
jne jonasLoop
endJonas:
addl %eax, iPos
leave
ret
/*Överför n (4 = buff 8 = tecken) tecken från pos och frammåt ifrån stacken
och lägg på in-bufferten, om det inte finns n tecken kvar så överför så mkt som det går.
Returnera alla de verkligen överförda tecknen*/
getchar:
/*Returnerar ett tecken ifrån in-bufferten, samt ökAr pos med 1.
Om det inte finns något att returnera så kallas inimage*/
enter $0,$0
pushl %ebx
pushl %ecx
pushl %edx
movl iPos, %ebx
cmpl $79, iPos
je awesomeImage
addl $iBuff, %ebx
movl $0, %eax
movb (%ebx), %al
addl $1, iPos
popl %edx
popl %ecx
popl %ebx
leave
ret
awesomeImage:
call inimage
leave
ret
getinpos:
enter $0,$0
movl iPos, %eax
leave
ret
/*Returnera pos*/
setinpos:
enter $0, $0
movl 8(%ebp), %eax
movl %eax, iPos
leave
ret
/*sätt pos till n. Dock pos måste ligga i intervallet [0,maxpos], för litet pos sätts
till 0 för stort till maxpos.
*/
/*Här börjar outimage och dess subrutiner*/
outimage:
/*Skriv ut bufferten och nollställ*/
enter $0,$0
pushl $oBuff
call puts
/*movl oPos, %ebx*/
Outloop:
subl $1, oPos
movl oPos, %ecx
addl $oBuff, %ecx
movl $0, (%ecx)
cmpl $oBuff, %ecx
jne Outloop
leave
ret
putint:
/*Lägg talet som finns i %eax i bufferten som en sträng (bara lägg ut det vill säga)
om man står vid buffertens slut så görs en outimage automatiskt
*/
enter $0,$0
movl 8(%ebp), %eax
movl $intBuff, %ecx
cmpl $0, %eax
jns fulLoop
pushl $'-'
call putchar
imul $-1, %eax
fulLoop:
movl $0, %edx
movl $10, %ebx
idiv %ebx
addl $'0', %edx
movl %edx, (%ecx)
inc %ecx
cmpl $0, %eax
jne fulLoop
hejLoop:
dec %ecx
pushl (%ecx)
call putchar
cmpl $intBuff, %ecx
jne hejLoop
leave
ret
puttext:
/*Lägg det som finns på stacken, i utbufferten
om texten inte får plats i utbufferten, kalla på outimage
och lägg sedan in texten.*/
enter $0,$0
movl 8(%ebp), %eax
annasLoop:
movb (%eax), %dl
pushl %edx
call putchar
inc %eax
cmp $0, %dl
jne annasLoop
leave
ret
//Om text från stack inte får plats i utbuffert
//kalla på outimage
putchar:
enter $0,$0
pushl %eax
pushl %edx
pushl %ebx
pushl %ecx
movb 8(%ebp), %al
movl $oBuff, %ebx
movl oPos, %ecx
addl %ecx, %ebx
movb %al, (%ebx)
addl $1, oPos
popl %ecx
popl %ebx
popl %edx
popl %eax
leave
ret
getoutpos:
/*Returnera ut-bufferpekarens position till %eax*/
enter $0,$0
movl oPos, %eax
leave
ret
setoutpos:
enter $0, $0
movl 8(%ebp), %eax
movl %eax, oPos
leave
ret
/*Sätt ut-bufferpekarens position till %eax*/
call exit
exit:
Code: Select all
//long här är 32 bitar
//word här är 16 bitar
.data
Head: .asciz "Start av testprogram. Skriv in 5 tal!"
Slut: .asciz "Slut på testprogram"
Buf: .skip 64 /*//== space 64 bytes*/
Sum: .long 0
N: .long 0
T: .long 0
.text
.global main
main:
pushl $Head
call puttext
/*pushl %ebp <- ska inte vara där*/
/*//lägg i bufferten det som finns (på adressen) i stacken, till //NULL*/
call outimage
call inimage
movl $5,N
Upp: call getint
movl %eax,T
cmpl $0,%eax
jge pp1
call getoutpos
decl %eax
pushl %eax
call setoutpos
pp1: movl T,%edx
addl %edx,Sum
pushl %edx
call putint
pushl $'+'
call putchar
decl N
cmpl $0,N
jne Upp
call getoutpos
decl %eax
pushl %eax
call setoutpos
pushl $'='
call putchar
pushl Sum
call putint
call outimage
pushl $12
pushl $Buf
call gettext
pushl $Buf
call puttext
pushl $125
call putint
call outimage
pushl $Slut
call puttext
call outimage
call exit