hallo!

bin noch anfänger in sachen assembler. habe ein beispiel prog fürs übertragen über RS232 gefunden.

hier:

Code:
.NOLIST
.INCLUDE "D:\m32def.inc"
.LIST

.equ fck = 4000000
.equ baudrate = 4800

.equ baudconst = (fck / (baudrate * 16)) - 1

.def w = R19				; Arbeitsregister
.def wi = R20				; Interrupt-Arbeitsregister
.def rs_buf = R21			; Buffer für empfangenes Byte
.def a_flag = R25			; Flagregister

.equ rs_recv = 0			; 1 = Byte empfangen - 0 = kein Byte empfangen


; Interrupt-Adressen
.cseg
.org $0000
	rjmp main

.org $0007					; RS232 Empfangsinterrupt
	rjmp rs232_recv			; RS232 Behandlungsroutinge wenn etwas empfangen wird



; I/O-Port Initialisierung:
hdw_init:
	ldi w, 0b11111111
	out PORTD, w			; alle Pins am Port D auf 1 setzen
	ldi w, 0b11111110
	out DDRD, w				; Datenrichtung am Port D festlegen: 1 = Ausgang; 0 = Eingang
							; Pin 1 am Port D Empfangen (= 1) RX
							; Pin 2 am Port D Senden (= 0) TX

	
	ldi w, 0b11111111
	out PORTB, w
	ldi w, 0b11111111
	out DDRB, w

	
	; UART Initialisierung:
uart_init:
	ldi w, baudconst
	out UBRRL, w			; UBRR = USART Baud Rate Register
	ldi w, 0
	out UBRRH, w
	ldi w, 0b00011000
	out UCSRB, w			; RXEN und TXEN setzen
	sbi UCSRB, RXCIE		; RS232 Interrupt freigeben


; PWM Initialisierung:
pwm_init:
	ldi w, 0b10000001
	out TCCR1A, w
	ldi w, 0
	out OCR1AH, w
	ldi w, 1
	out OCR1AL, w
	ldi w, 0b00000001
	out TCCR1B, w

	sei						; gibt alle Interrups frei
	ret


; Behandlung für empfangene Bytes:
rs_rec_up:
	cbr a_flag, 1 << rs_recv; durch '1<<' wird eine '1' n-mal nach links geschoben
							; für rs_recv = 0: 0b00000001
							; für rs_recv = 1: 0b00000010
							; --> das erste bzw zweite Bit in a_flag wird somit gelöscht

	mov w, rs_buf			; empfangenes Byte in w
	out PORTB, w			; an Port B ausgeben ?(kein PWM)?
	out OCR1AL, w
	rcall rs_send
	ret


rs_send:
	sbis UCSRA, UDRE		; überprüft, ob UDRE im Register UCSRA gesetzt ist, wenn ja (UDRE=1) überspringen
							; UDRE = 1 Sender frei, UDRE = 0 Sender besetzt
	rjmp rs_send
	out UDR, w
	ret


; Interruptroutine wenn Bytes empfangen werden:
rs232_recv:
	in wi, SREG				; CPU-Status
	push wi					; wi in Stackpointer
	
	in wi, UDR				; Byte vom Empfänger laden
	mov rs_buf, wi			; zwischenspeichern
	sbr a_flag, 1<<rs_recv	; durch '1<<' wird eine '1' n-mal nach links geschoben
							; für rs_recv = 0: 0b00000001
							; für rs_recv = 1: 0b00000010
							; --> das erste bzw zweite Bit in a_flag wird somit gesetzt

	pop wi					; Stackpointer zurück in wi
	out SREG, wi			; zurück zur CPU
	
	reti					; Return from Interrupt


main:
	ldi w, RAMEND			; RAMEND: Speicherende des Chips
	out SPL, w				; in Stackpointer schreiben
	clr a_flag
	rcall hdw_init			; Hardware Initialisierung

endlos:
	sbrc a_flag, rs_recv
	rcall rs_rec_up			; wenn was empfangen wurde dann...
	rjmp endlos				; sonst warten
die komentare sind von mir. können also auch falsch sein

geht man das prog schritt für schritt durch, springt er hier 'rcall hdw_init' in den initialisierungsteil. am ende von 'pwm_init:' steht ein 'ret'. an dieser stelle springt er aber dann nicht zurück zum 'rcall hdw_init' bzw in die endlosschleife, sondern springt ganz an den anfang zu: '.org $0000 rjmp main'

woran liegt das?

wird in 'main:' der stackpointer falsch beschrieben? was genau bedeutet denn RAMEND?

danke mal für eure geduld wenn ihr bis zum schluss gelesen habt! \/

freddy0815