CLI and STI are not working

孤人 提交于 2019-12-22 13:59:29

问题


I am an beginner in x86 assembly. I have compiled a small operating system (compiled with nasm onto a floppy disk), and I am having some trouble with it. This operating sysem is designed to turn on Caps, Scroll, and Num Lock, then wait for half of a second, then turn them off, then wait half a second. Then it repeats.

The problem is at the lines cli and sti. This should be enabled to ensure atomicity, so the timing is correct for Wait_Clk_Ticks. When these lines are put into the program, the lights turn on, but that is all. When they are not in the program, the lights blink on and off as they should. What is wrong with this code?

Are the jmp functions in the Wait_Clk_Ticks code causing an interrupt? I am told that cli and sti are used to disable hardware interrupts. Does jmp cause a hardware interrupt?

Code:

; 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

I am running this code with a USB keyboard on an IBM 8307.

Thanks for your help :)


回答1:


Don't you think cli also disables the clock interrupt, and the timer stops?




回答2:


No, the jmp doesn't cause an interrupt... but the timer tick does... or would, if you didn't turn 'em off!

This is probably more than you need, but as I recall it used to work. Happy bootin'!

; 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
;---------------



来源:https://stackoverflow.com/questions/17037142/cli-and-sti-are-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!