简体   繁体   English

组装x86延迟循环

[英]Assembly x86 Delay loop

hi i made program that will rotate two symbols - \\ and / but i dont know how to set cx counter in nested loops can someone give me advice or help me ? 嗨,我制作了将旋转两个符号的程序-\\和/,但我不知道如何在嵌套循环中设置cx计数器,有人可以给我建议还是帮助我?

here is the code of that part 这是那部分的代码

program:  
      mov ah, 0fh   ; function - get video mode
      int 10h
      push ax       ; save number of columns
      push bx       ; save page number
      mov ah, 0     ; function - set video mode
      int 10h

      mov al, 0003h     ;set video mode
      int 10h

      mov cx,10d  ; Outer loop counter how many symbols rotate

      mov bx,50d  ;   this is for delay loop
      OuterLoop:
      push cx

      mov ah,02h
      mov bh, 0        ;cursor set
      mov dh, 2
      mov dl, 10
      int 10h

      mov AH,0Ah
      mov al,"/"    symbol /
      mov bh,0
      mov cx,1
      int 10h

      mov cx,bx
      call Delay       ;delay loop
      sub bx,15d

      mov ah,02h
      mov bh, 0
      mov dh, 2            cursor set
      mov dl, 10
      int 10h

      mov AH,0Ah
      mov al,"\"             ;symbol \
      mov bh,0 
      mov cx,1
      int 10h


      mov cx,bx
      call Delay  ; another delay
      sub bx,10


      pop cx       ; Restore current CX
      loop OuterLoop

      jmp START     ; and after end it should jump to start where is menu with choices

it should work like this 它应该像这样工作

write / delay for example 10 sec write \\ delay 8 sec and jump to beginning and loop 写入/延迟,例如10秒写入\\延迟8秒,然后跳转到开始并循环

thanks for advices 感谢您的建议

this is my delay procedure 这是我的延误程序

Delay   PROC    NEAR                    ;

    push    ds                      ;
    push    si                      ;
    push    ax                      ;
    xor     ax, ax                  ;AX = 0
    mov     ds, ax                  ;DS = 0
    mov     si, 046Ch               ;
t1:     mov     ax, [si]                ;
t2:     cmp     ax, [si]                ;
    je      t2                      ;
    loop    t1                      ;
    pop     ax                      ;
    pop     si                      ;
    pop     ds                      ;
    ret                             ;

Delay   ENDP                            ;

i am still working on this app but it is not working all i need is this steps to be made 我仍在使用此应用程序,但它不起作用,我需要做的就是以下步骤

program : start of loop \\ delay delay 100 times / delay delay 80 times loop and after every loop to decrease delay like this 100 times 80,60,40 and so on but i dont know where to put push and pop cx because my delay procedure is working with cx. 程序:循环的开始\\延迟延迟100次/延迟延迟80次循环,每次循环之后都可以像这样减少100倍延迟80、60、40,依此类推,但是我不知道将push和pop cx放在哪里,因为我的延迟过程正在使用cx。 i just set cx for example to 100 and it makes delay and so on. 我只是将cx设置为100,这会导致延迟等等。

I see two problems: 我看到两个问题:

First, bx is initialized here 首先, bx在这里初始化

mov bx,50d  ;   this is for delay loop

but then it gets over-written by 但随后它被覆盖

mov bh, 0

bh is bits 15:8 of bx bhbx 15:8

Second, in the Delay procedure, what modifies the location at [si] so that the je t2 branch falls thru? 其次,在“延迟”过程中,是什么修改了[si]处的位置,以便je t2分支通过? As it stands that is an infinite loop: 就目前而言,这是一个无限循环:

xor     ax, ax                  ;AX = 0
mov     ds, ax                  ;DS = 0
mov     si, 046Ch               ;
t1:     mov     ax, [si]        ;
t2:     cmp     ax, [si]        ;
        je      t2              ;
        loop    t1              ;

Update: I found that address 0x46c is a BIOS address that contains time information. 更新:我发现地址0x46c是包含时间信息的BIOS地址。

http://www.osdata.com/system/physical/lowmem.htm http://www.osdata.com/system/physical/lowmem.htm

So the memory you are watching in that loop is a location updated by BIOS with a counter of timer ticks (counts every 54.9 milliseconds), see 因此,您在该循环中正在查看的内存是BIOS更新的位置,带有计时器滴答计数器(每54.9毫秒计数一次),请参阅

http://code.google.com/p/xtideuniversalbios/source/browse/trunk/Assembly_Library/Src/Time/TimerTicks.asm?spec=svn131&r=131 http://code.google.com/p/xtideuniversalbios/source/browse/trunk/Assembly_Library/Src/Time/TimerTicks.asm?spec=svn131&r=131

So to answer your question, before calling your Delay procedure you should load CX with the count of BIOS ticks you wish to delay (time in milliseconds divided by 54.9). 因此,为回答您的问题,在调用“ Delay过程之前,应使用希望延迟的BIOS滴答计数(以毫秒为单位的时间除以54.9)加载CX

For to drawing my own cursor i use the timer interrupt for to become a more steady delay on different performant CPUs. 为了绘制自己的光标,我使用了定时器中断来在不同性能的CPU上变得更稳定。

Cursor_Speed = 7
;-------------DATA--------------------------------------
          CURFLAG DB 0, 0, 0, 0
          ALTVEC  DD 0
;-------------CODE--------------------------------------
          cli
          xor      ax, ax
          mov      es, ax
          mov      ebx, DWORD PTR es:[8*4] ; Get the old Vector (Offset/Segment)
          mov     DWORD PTR[ALTVEC], ebx   ; save it
          mov     cs:DWORD PTR[OLDVEC], ebx
          mov      es:[8*4], OFFSET NEWVEC ; Set the new IRQ-Vector
          mov      es:[(8*4)+2], cs

          mov      al, 36h                    ; Set 18,2 Hertz(Standard)
          out      43h, al
          xor      al, al
          out      40h, al           ; low
          out      40h, al           ; high
          sti
;---------------------------------------------------
          ......
;---------------------------------------------------
NEWVEC:   inc     BYTE PTR[CURFLAG+1]
          cmp     BYTE PTR[CURFLAG+1], Cursor_Speed
          jb  short NOHIT
          mov     BYTE PTR[CURFLAG+1], 0
          xor     BYTE PTR[CURFLAG], 1

NOHIT:    DB 0EAh                         ; jmp far
OLDVEC    DD 0
;---------------------------------------------------

.... ....

Alternativly we can wait of the vsinc with polling port 3DAh for to become a little bit lesser precice delay. 或者,我们可以等待带有轮询端口3DAh的vsinc来减少一点延迟。

Dirk 短剑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM