All pastes #1503210 Raw Edit

Anonymous

public text v1 · immutable
#1503210 ·published 2009-07-22 13:31 UTC
rendered paste body
	STKSZ	equ	16*1024
	CODEP	equ	0
	FLAGSP	equ	4
	SPP	equ	8
	BUFFCNT	equ	10

section .rodata
	align 16

	global	numco
numco:	dd	4
CORS:	dd	CO1
	dd	CO2
	dd	CO3
	dd	CO4

section .data
	align 16
; Structure for first co-routine (writer)
CO1:	dd	Function1
Flags1:	dd	0
SP1:	dd	STK1+STKSZ

; Structure for second co-routine (reader1)
CO2:	dd	Function2
Flags2:	dd	0
SP2:	dd	STK2+STKSZ

; Structure for third co-routine (reader2)
CO3:	dd	Function3
Flags3:	dd	0
SP3:	dd	STK3+STKSZ

; Structure for forth co-routine (scheduler)
CO4:	dd	Function4
Flags4:	dd	0
SP4:	dd	STK4+STKSZ

SWITCH:	dd	0 ; indicator - reader1/reader2
EXIT: 	db	0 ; indicator - becomes 1 if we should exit
FINISH:	db	0 ; indicator - becomes 1 if input is fully written
MUX:	db	1 ; indicator - which reader to choose

section .bss
	align 16
CURR:	resd	1
SPT:	resd	1
SPMAIN:	resd	1
STK1:	resb	STKSZ
STK2:	resb	STKSZ
STK3:	resb	STKSZ
STK4:	resb	STKSZ
BUFFER:	resb	4
INPUT:	resb	4
BUFF:	resb	4

section .text
	align 16
	extern	printf
	extern 	gets
	global	init_co_from_c
	global	start_co_from_c
	global	end_co


; Initalize a co-routine number given as an argument from C
init_co_from_c:
	push	EBP
	mov	EBP, ESP
	push	EBX

	mov	EBX, [EBP+8]
	mov	EBX, [EBX*4+CORS]

	call	co_init

	pop	EBX
	pop	EBP
	ret
	

;  EBX is pointer to co-routine structure to initialize
co_init:
	pusha
	bts	dword [EBX+FLAGSP],0  ; test if already initialized
	jc	init_done
	mov	EAX,[EBX+CODEP] ; Get initial PC
	mov	[SPT], ESP
	mov	ESP,[EBX+SPP]   ; Get initial SP
	mov	EBP, ESP        ; Also use as EBP
	push	EAX             ; Push initial "return" address
	pushf                   ; and flags
	pusha                   ; and all other regs
	mov	[EBX+SPP],ESP    ; Save new SP in structure
	mov	ESP, [SPT]      ; Restore original SP
init_done:
	popa
	ret

; EBX is pointer to co-init structure of co-routine to be resumed
; CURR holds a pointer to co-init structure of the curent co-routine
resume:
	pushf			; Save state of caller
	pusha
	mov	EDX, [CURR]
	mov	[EDX+SPP],ESP	; Save current SP
do_resume:
	mov	ESP, [EBX+SPP]  ; Load SP for resumed co-routine
	mov	[CURR], EBX
	popa			; Restore resumed co-routine state
	popf
	ret                     ; "return" to resumed co-routine!

; C-callable start of the first co-routine
start_co_from_c:
	push	EBP
	mov	EBP, ESP
	pusha
	mov	[SPMAIN], ESP             ; Save SP of main code

	mov	EBX, [EBP+8]		; Get number of co-routine
	mov	EBX, [EBX*4+CORS]       ; and pointer to co-routine structure
	jmp	do_resume


; End co-routine mechanism, back to C main
end_co:
	mov	ESP, [SPMAIN]            ; Restore state of main code
	popa
	pop	EBP
	ret
	

; Example functions using co-routine mechanism

WRITERES:	db	"Writer Resumes.", 10, 0
READ1RES:	db	"Reader1 Resumes.", 10, 0
READ2RES:	db	"Reader2 Resumes.", 10, 0
SCHEDRES:	db 	"Scheduler Resumes.", 10, 0

WRITER:		db	"Writer: %s", 10, 0
READ1:		db	"Reader1: %s", 10, 0
READ2:		db	"Reader2: %s", 10, 0
SCHED:		db 	"Scheduler: %s", 10, 0

WRITEPROM:	db	"Writer: Hello, master. What can I write and read for you today? ", 0
WRITING:	db	"Writer: Writing %s.", 10, 0
WRITEFIN:	db	"Writer: I have finished writing your words of wisdom, sir.", 10, 0

READSORR:	db	"Terribly sorry, sir. The buffer is locked by the writer.", 0
READFIN1:	db	"Reader1: Ah, a fine read, sir. You wrote: %s.", 10, 0
READFIN2:	db	"Reader2: Ah, a fine read, sir. You wrote: %s.", 10, 0

GOODBYE:	db	"Goodbye, master.", 0

; This function used as code for co-routines 0 and 1
Function1:
	push 	dword WRITERES ; display resume
	call	printf
	add	esp, 4
NeWInput:
	push	dword WRITEPROM
	call	printf
	add	esp, 4
	mov	ecx, INPUT
	pusha
	push	ecx
	call	gets
	add	esp, 4
	popa
	pusha
	push	ecx
	call	printf
	add	esp, 4
	popa
	mov	byte[FINISH], 0
	cmp	byte[ecx], 113 ; q
	je	quit
	mov	edx, BUFF
loop_init:
	mov	esi, 0 ; loop counter till 10
	mov	ebx, BUFFER
func1_loop:	
	mov	al, byte[ecx]
	cmp	al, 0
	je	end_string	
	mov	byte[ebx], al
	;mov	byte[edx], al
	inc	ebx
	inc	ecx
	;inc	edx
	inc	esi
	cmp	esi ,BUFFCNT
	jne	func1_loop
end_10_chars:
	mov	byte[ebx], 0
	pusha
	push	dword BUFFER
	push	dword WRITING
	call	printf
	add	esp, 8
	popa
	mov	ebx, [CORS + 12]
	call	dword resume
	pusha
	push 	dword WRITERES ; display resume
	call	printf
	add	esp, 4
	popa
	jmp	loop_init
end_string:
	mov	byte[FINISH], 1
	mov	byte[ebx], 0
	;mov	byte[edx], 0
	pusha
	push	dword BUFFER
	push	dword WRITING
	call	printf
	add	esp, 8
	popa
	pusha
	push	dword WRITEFIN
	call	printf
	add	esp, 4
	popa
	mov	ebx, [CORS + 12]
	call	dword resume
	jmp	Function1
quit:
	mov	byte[EXIT], 1
	pusha
	push	dword GOODBYE
	push 	dword WRITER
	call	printf
	add	esp, 8
	popa
	mov	ebx, [CORS + 12]
	call	dword resume

; This function used as code for co-routine 2
Function2:
first_reader:
	mov 	eax, READ1RES
	pusha
	push	eax
	call	printf
	add	esp, 4	
	popa
	cmp	byte[EXIT], 1
	je	goodbye1
	cmp	byte[FINISH], 1
	jne	sorry1
read_buffer1:
	pusha
	push	dword INPUT
	push	dword READFIN1
	call	printf
	add	esp, 8
	popa
	jmp	func2_loop1
sorry1:
	push	dword READSORR
	push	dword READ1
	call	printf
	add	esp, 8
	jmp	func2_loop1
goodbye1:
	push	dword GOODBYE
	push	dword READ1
	call	printf
	add	esp, 8
func2_loop1:
	mov	ebx, [CORS + 12]
	call	dword resume
	jmp	first_reader
	
; This function used as code for co-routine 3
Function3:
second_reader:
	mov 	eax, READ2RES
	push	eax
	call	printf
	add	esp, 4
	cmp	byte[EXIT], 1
	je	goodbye2
	cmp	byte[FINISH], 1
	jne	sorry2
read_buffer2:
	push	dword INPUT
	push	dword READFIN2
	call	printf
	add	esp, 8
	jmp 	func2_loop2
sorry2:
	push	dword READSORR
	push	dword READ2
	call	printf
	add	esp, 8
	jmp 	func2_loop2
goodbye2:
	push	dword GOODBYE
	push	dword READ2
	call	printf
	add	esp, 8
func2_loop2:
	mov	ebx, [CORS + 12]
	call	dword resume
	jmp	second_reader
	
; This function used as code for co-routine 3

Function4:
Writer:
	push	dword SCHEDRES
	call	printf
	add	esp, 4
	mov	ebx, [CORS]
	call	dword resume
	push	dword INPUT;
	call	printf
	add	esp, 4
	cmp	byte[EXIT], 1
	je	Reader1
	cmp	byte[MUX], 2
	je	Reader2
Reader1:
	push	dword SCHEDRES
	call	printf
	add	esp, 4
	mov	ebx, [CORS + 4]
	call	dword resume
	mov	byte[MUX], 2
	cmp	byte[EXIT], 1
	jne	Writer
Reader2:	
	push	dword SCHEDRES
	call	printf
	add	esp, 4
	mov	ebx, [CORS + 8]
	call	dword resume
	mov	byte[MUX], 1
	cmp	byte[EXIT], 1
	jne	Writer
finish:
	push	dword SCHEDRES
	call	printf
	add	esp, 4
	cmp	byte[EXIT], 1
	jne	Function3
	push	dword GOODBYE
	push	dword SCHED
	call 	printf
	add	esp, 8
	jmp	end_co