Dem Snippet fehlt etwas Assembler-Kontext, also dachte ich zuerst, es wäre Nasm, aber dann habe ich auf StackOverlow herausgefunden, dass es Gas war mit der .intel_syntax noprefix-Direktive (z. B. Kommentare zu: intel_syntax noprefix, intel_syntax noprefix).
Ich habe das alles naiv gemacht und gedacht, dass dies „nur eine weitere (harmlose) Hallo-Welt-Sache wie immer“ sein würde, aber ich denke, das ist nicht der Fall.
Nachdem ich die erforderlichen Abschnitte abgeschlossen hatte, funktionierte das Programm (sowohl in Nasm als auch in Gas), aber ich bekam einen Segmentierungsfehler, also beschloss ich, das Problem zu verfolgen (
Code: Select all
gdbWarum verursacht das Löschen des Interrupt-Flags einen Segmentierungsfehler in C?
Das hat mich ziemlich erschreckt, denn wenn ich es richtig verstanden hätte, kann es zu dauerhaften Hardware-Zustandsfehlern kommen (zumindest die CPU-Cli wurde darauf hingewiesen)? Eine Art „Zahnriemenbruch im Auto“? Schwerwiegender Synchronisationsverlust in der Logik dieser CPU? Unumkehrbar oder zumindest ein tiefgreifender Albtraum einer Wiederherstellungsaufgabe?
Die Frage ist, ob im Kontext des erwähnten Codes („Testen der A20-Zeile“, siehe unten) die Verwaltung von cli sicher ist (z. B. „zumindest in diesem Codeausschnitt zeigen Sie, dass alles bezüglich cli korrekt wiederhergestellt ist...“) und man es sogar mit sudo ohne Probleme starten kann Die Antwort lautet: Führen Sie keine uninformierten privilegierten Experimente mit CLI--Anweisungen durch. Obwohl ich das alles in einer VM mache, ist es auch nicht lustig, es zu vermasseln.
Wenn die Antwort lautet: Es ist nicht sicher. Gibt es eine Alternative dazu
im selben Low-Level-Geist?
Code in der betreffenden Codequelle:
Code: Select all
.func CheckA20
CheckA20:
pushf # Save registers that
push ds # we are going to
push es # overwrite.
push di
push si
cli # No interrupts, please
xor ax, ax # Set es:di = 0000:0500
mov es, ax
mov di, 0x0500
mov ax, 0xffff # Set ds:si = ffff:0510
mov ds, ax
mov si, 0x0510
mov al, byte ptr es:[di] # Save byte at es:di on stack.
push ax # (we want to restore it later)
mov al, byte ptr ds:[si] # Save byte at ds:si on stack.
push ax # (we want to restore it later)
mov byte ptr es:[di], 0x00 # [es:di] = 0x00
mov byte ptr ds:[si], 0xFF # [ds:si] = 0xff
cmp byte ptr es:[di], 0xFF # Did memory wrap around?
pop ax
mov byte ptr ds:[si], al # Restore byte at ds:si
pop ax
mov byte ptr es:[di], al # Restore byte at es:di
mov ax, 0
je check_a20__exit # If memory wrapped around, return 0.
mov ax, 1 # else return 1.
check_a20__exit:
pop si # Restore saved registers.
pop di
pop es
pop ds
popf
ret
.endfunc
Code: Select all
gdbCode: Select all
(gdb) r
Starting program: /home/peter/Documents/.../hardware
_assembly/checkA20_gas
…
(gdb) si
16 cli # No interrupts, please
(gdb) si
Program received signal SIGSEGV, Segmentation fault.
CheckA20 () at checkA20_gas.s:16
16 cli # No interrupts, please
Code: Select all
nasmCode: Select all
$ ./checkA20
zsh: segmentation fault (core dumped) ./checkA20
Code: Select all
gasCode: Select all
$ ./checkA20_gas
zsh: segmentation fault (core dumped) ./checkA20_gas
Code: Select all
$ ./poc_cli
zsh: segmentation fault (core dumped) ./poc_cli
Code: Select all
$ cat poc_cli.s
.intel_syntax noprefix
.text
.global _start
_start:
cli
mov ebx, eax
mov eax, 1
int 0x80
Mobile version