2

私は x86 アセンブリの初心者です。小さなオペレーティング システム (nasm を使用してフロッピー ディスクにコンパイル) をコンパイルしましたが、問題が発生しています。このオペレーティング システムは、Caps、Scroll、および Num Lock をオンにしてから 0.5 秒待ってからオフにし、さらに 0.5 秒待つように設計されています。それが繰り返されます。

問題は と の行cliにありstiます。これは原子性を確保するために有効にする必要があるため、タイミングはWait_Clk_Ticks. これらの行をプログラムに入れると、ライトが点灯しますが、それだけです。それらがプログラムにないとき、ライトは必要に応じてオンとオフを点滅します。このコードの何が問題になっていますか?

コード内のjmp関数がWait_Clk_Ticks割り込みを引き起こしていますか? ハードウェア割り込みを無効にするために使用されているcliと言われています。ハードウェア割り込みを発生させますかsti?jmp

コード:

; blinklights.asm



[BITS 16]
[ORG 0x7C00]

jmp Code_Start


Switch_Kbd_Leds:

    push dx     ; Store current values.
    push ax

    mov dx, 60h ; '60h' is the 'kbd' port value.
    mov al, 0EDh    ; '0EDh' is 'set/reset leds' function.
    out dx, al  ; Then output to the port.

    pop ax      ; Get the setting from the stack.
    out dx, al  ; Output this data to the port.

    pop dx      ; Restore 'dx'.
    ret     ; Return.

Wait_Clk_Ticks:


    cli

    mov  ax, 0
    mov  ds, ax
    mov  bx, [46Ch]
    WaitForAnotherChange:
    NoChange:
    mov  ax, [46Ch]
    cmp  ax, bx
    je   NoChange
    mov  bx, ax
    loop WaitForAnotherChange

    sti

    ret     ; Return.

Code_Start:
    mov al, 00000111b
    call Switch_Kbd_Leds

    mov cx, 9
    call Wait_Clk_Ticks

    mov al, 00000000b
    call Switch_Kbd_Leds

    mov cx, 9
    call Wait_Clk_Ticks

    jmp Code_Start



End:
    jmp $       ; Run this line over and over again- stops excecution.

times 510-($-$$) db 0   ; Fill the rest of the 512 byte sector with zeros
dw 0xAA55       ; Boot magic number

IBM 8307 の USB キーボードでこのコードを実行しています。

ご協力いただきありがとうございます :)

4

2 に答える 2

2

cli もクロック割り込みを無効にして、タイマーが停止すると思いませんか?

于 2013-06-11T07:00:02.530 に答える
1

いいえ、jmp割り込みは発生しません...しかし、タイマーティックは発生します...または、オフにしなければ発生します!

これはおそらく必要以上のものですが、私が思い出したように、以前は機能していました。ハッピーブート!

; nasm -f bin -o kblites.com  kblites.asm

org 100h

section .text

    mov al, 4          ; set a starting mask - caps-lock
go:
    call set_lites
    jc .error

    push ax
    mov ah, 1           ; get a key and echo it
    int 21h             ; (just to demo that caps-lock
    cmp al, 1Bh         ; is working independent of the leds)
    pop ax

    jz .exit            ; quit if ESC hit

    shr al, 1           ; else change mask and go again
    jnz go
    mov al, 4
    jmp short go

.error:
    mov al, 'E'
    int 29h

.exit:
    mov ah, 4Ch
    int 21h
;--------------


;-------------------------------
; set_lites
; expects - a mask to set the keyboard leds in al
; bit 0 - scroll-lock, bit 1 - num-lock, bit 2 - caps-lock
; other bits should be 0
; returns - carry set on error
;-------------------------------
set_lites:
    push cx            ; save caller's reg
    push ax            ; al has our desired led mask
;    xor cx, cx         ; retry counter, so we don't loop forever
    or cx, byte -1
.top:
    in al, 64h         ; get keyboard status byte
    test al, 3         ; wait until we're okay to write
    jz .good
    in al, 60h         ; flush any input waiting
    dec cx
    jz .got_ack
    jmp short .top     ; try again
.good:
    mov al, 0EDh       ; set led command
    out 60h, al
.get_ack:
    in al, 60h         ; wait for acknowledgement
    cmp al, 0FAh       ; curiously, this isn't neccessary
    jz .got_ack        ; when running in a "dos-box", but
    dec cx             ; "real dos" requires it (?).
    jz .got_ack
    jmp short .get_ack
.got_ack:              ; bail out if we never get it
    pop ax             ; get our led mask back
    out 60h, al        ; set 'em!
    cmp cx, byte 1     ; set carry if retry-counter ran out
    pop cx             ; restore caller's reg
    ret
;---------------

于 2013-06-11T09:20:47.853 に答える