Ich versuche ein Board mit einem x86 Derivat (SC520) in Betrieb zu
nehmen. Damit ich nicht ganz im Dunkeln stehe, will ich über die
serielle Schnittstelle Lebenszeichen ausgeben. Dazu habe ich folgenden
Code zum funktionieren gebracht:
LSR equ 03FDh
THR equ 03F8h
mov edx,LSR
Wait1:
in al,dx
and al,20h
jz Wait1
mov edx,THR
mov al,'#'
out dx,al ; << Ausgabe 023h '#'
Die CPU is im 386 Protected Mode, linares Adress Modell.
(CS=DS=SS=ES:4 Gigabyte, Basisadresse 0).
Jetzt soll ein Text ausgegeben werden. Diesen habe ich in das
Codesegment gelegt, damit kein extra Datensegment in der ASM Datei
angelegt werden muss:
jmp weiter
mein_text:
db 'K'
weiter:
mov edx,LSR
Wait2:
in al,dx
and al,20h
jz Wait2
mov esi,OFFSET32 mein_text
mov al,cs:[esi]
mov edx,DBGTHR
out dx,al ; << Ausgabe 0FFh
Der Sinn, die Zeichen aus dem Speicher zu lesen bevor sie ausgegeben
werden, besteht darin, dass hier noch eine Schleife mit Textendekennung
etc. folgen soll.
Warum bekomme ich nicht das Byte, das im Codesegment steht, sondern nur
0FFh?
Harper Blues schrieb: > (CS=DS=SS=ES:4 Gigabyte, Basisadresse 0). Bei CS=DS ist ein Präfix unnötig, sollte aber auch nicht stören.
A. K. schrieb: > mov edx,THR > vs > mov edx,DBGTHR > ? ??? Aber dann dürfte ja auch kein 0xFF gesendet werden.
A. K. schrieb: > mov edx,THR > vs > mov edx,DBGTHR > ? Danke für den Hinweis. Dabei handelt es sich um einen Tippfehler beim übertragen des Codes zu diesem Forum. Da mehr als eine UART im Projekt beteiliegt ist, wird die DBG-Schnittstelle mit dem Prefix DBG versehen. Das ist für diese Frage aber nicht relevant. Da an der UART ein Zeichen ausgegeben wird, es es genau 03F8h. Korrekt muss es so aussehen: jmp weiter mein_text: db 'K' weiter: mov edx,LSR Wait2: in al,dx and al,20h jz Wait2 mov esi,OFFSET32 mein_text mov al,cs:[esi] mov edx,THR out dx,al ; << Ausgabe 0FFh
A. K. schrieb: > Harper Blues schrieb: >> (CS=DS=SS=ES:4 Gigabyte, Basisadresse 0). > > Bei CS=DS ist ein Präfix unnötig, sollte aber auch nicht stören. Genau, habe ich ausprobiert. Gleiches Resultat. Ich habe nun doch mal ein Datensegment aufgemacht, was aber erwartungsgemß auch keine Änderung bringt: ASSUME CS: FLAT, DS: FLAT, SS: FLAT _DATA SEGMENT para public 'DATA' my_data db '@' _DATA ENDS _TEXT SEGMENT para public 'TEXT' ; ..... mov esi,OFFSET32 my_data mov al,[esi] mov edx,THR out dx,al _TEXT ENDS Ich habe mit objdump kontrolliert, dass das Byte 040h tatsächlich im Datensegement ist.
Tja, das konnte ja auch nicht funktioneren. Der Context in dem der Code
ausgeführt werden soll, ist unmitelbar vor dem Laden der GDT.
Der Code liegt auf physisch auf der Adrese 00200000h, in der GDT wird
aber 80200000h bzw A0200000 eingetragen werden. Da Adressen, die vom
OFFSET32 xxx generiert werden lagen in dem Bereich, die erst nach dem
Laden der GDT auf den pyhsikalischen Speicher ausgeführt werden. Das
konnte ich jetzt durch folgenden Workaround benutzbar machen:
ESI_PhysicalAddress PROC NEAR
push eax
call physical_address
physical_address:
pop eax
sub esi, OFFSET32 physical_address
add esi,eax
pop eax
ret
ESI_PhysicalAddress ENDP
StartUp PROC NEAR
; .....
mov esi,OFFSET32 my_data
call ESI_PhysicalAddress
mov al,[esi]
mov edx,THR
out dx,al
; .....
StartUp ENDP
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.