如何设置定时器

2023-12-23

有什么办法可以将计时器设置为 60 秒xor ah,ah

 Enter_Again:
    xor ah, ah ; I should put 60 seconds here
    int 16h    ; The user should press S before 60 seconds
    mov bl,al
            cmp al,"S"

您之前的问题表明您正在 DOS 下运行。没有 BIOS 或 DOS 调用导致键盘输入超时。你可以锁住(链条)中断0x1c http://vitaly_filatov.tripod.com/ng/asm/asm_001.14.html这是一个用户中断例程,每秒调用大约 18.2 次。一分钟大约有 1092 个这样的中断。您的计时器中断可以简单地调用旧的用户中断,然后增加滴答计数。

Your main program can then check if a key has been pressed with BIOS call Int 16h/AH=1 http://www.ctyme.com/intr/rb-1755.htm. If the Zero Flag (ZF) is set by this call no key is present in the keyboard buffer. This call doesn't block waiting for characters, it only checks if the keyboard buffer is empty and if it isn't returns the most recent key without removing it from the buffer. You will want to use Int 16h/AH=0 http://www.ctyme.com/intr/rb-1754.htm to remove the character from the keyboard buffer IF one has been pressed and then check if it was S. The ASCII value of the key pressed is in register AL. Failure to remove the character from the buffer will not allow you to properly check the keyboard buffer in the future for the next character.

如果您要查找的键尚未被按下,那么您只需将当前全局计时器滴答计数与 1092 进行比较。如果尚未达到,您将返回并再次检查键盘缓冲区中的字符。

This sample code sets up a user timer interrupt handler and uses the basic mechanism described above to wait for S to be pressed. If it times out the program exits with a message indicating that. If S is pressed before the time out expires the program prints a message to that effect and then exits. Before exiting back to DOS the interrupt vectors need to be restored to what they were when the program started.

.model small
.stack 100h

KBD_TIMEOUT EQU 60*182/10       ; 1092 = ~60 seconds (18.2hz*60)
                                ; Max timer value is 65535 which is approximately
                                ; 3600 seconds (one hour)
.data
s_in_time_str     db "'S' pressed within 60 seconds$"
s_not_in_time_str db "'S' NOT pressed within 60 seconds$"

.code

; User timer interrupt handler called by Int 08h
; It occurs approximately every 18.2 times a second
; Upon entry CS is the only register that has an expected value
; CS is the code segment where the interrupt handler and the
; interrupt handler data reside

user_timer_int PROC
    ; Call (chain) to the original interrupt vector
    ; by pushing flags register and doing a FAR CALL to old vector
    pushf
    call dword ptr [cs:int1c_old_ofs]

    ; Increase timer tick by 1
    inc word ptr [cs:timer_tick]

    iret
user_timer_int ENDP

; Setup interrupt handlers needed by this program
set_interrupts PROC
    push ds

    ; Hook our timer interrupt handler to the user interrupt timer vector
    mov ax, 351ch               ; AH=35h (Get interrupt vector)
                                ; AL=1Ch (User timer interrupt vector)
    int 21h                     ; Get interrupt vector
    ; Int 21h/ah=35 will return interrupt vector address in ES:BX
    mov [cs:int1c_old_ofs], bx
    mov ax, es
    mov [cs:int1c_old_seg], ax

    mov ax, 251ch               ; AH=25h (Set interrupt vector)
                                ; AL=1Ch (User timer interrupt vector)
    ; Set DS:DX to our user interrupt routine
    ; DS:DX = CS:user_timer_int
    push cs
    pop ds
    mov dx, offset user_timer_int
    int 21h                     ; Set interrupt vector

    pop ds
    ret
set_interrupts ENDP

; Restore interrupts to original state
restore_interrupts PROC
    push ds

    ; Restore user timer interrupt vector to original routine
    mov ax, 251ch               ; AH=25h (Set interrupt vector)
                                ; AL=1Ch (User timer interrupt vector)
    ; Set DS:DX to our user interrupt routine
    ; DS:DX = CS:user_timer_int
    mov dx, [cs:int1c_old_ofs]
    mov cx, [cs:int1c_old_seg]
    mov ds, cx
    int 21h                     ; Set interrupt vector

    pop ds
    ret
restore_interrupts ENDP

main PROC
    mov ax, @data
    mov ds, ax                  ; Initialize the data segment

    call set_interrupts

    ; Reset timer to 0
    mov word ptr [cs:timer_tick], 0
    sti                         ; Ensure interrupts are enabled

key_chk_loop:
    hlt                         ; Wait (HLT) until next interrupt occurs

    mov ah, 1
    int 16h                     ; AH=1 BIOS Check if keystroke pressed
                                ; ZF flag set if no key pressed, AL=ASCII char pressed
    jz no_key                   ; If no key pressed check if we have timed out
    mov ah, 0
    int 16h                     ; AH=0 BIOS get keystroke (removes it from keyboard buffer)
                                ; If a key has been pressed we need to remove it from the
                                ; keyboard buffer with Int 16/AH=0.

    cmp al, 'S'                 ; If a key has been pressed was it 'S'?
    je s_in_time                ;     If so print pressed message and exit

no_key:
    ; Check if the counter has reached the timeout
    cmp word ptr [cs:timer_tick], KBD_TIMEOUT
    jb key_chk_loop             ; If time out hasn't been reached go back&check kbd again

timed_out:
    ; Print timed out message and exit
    mov ah, 9h
    mov dx, offset s_not_in_time_str
    int 21h
    jmp finished

s_in_time:
    ; Print success message and exit
    mov ah, 9h
    mov dx, offset s_in_time_str
    int 21h

finished:
    ; Restore interrupts to original state before returning to DOS
    call restore_interrupts

    ; Exit back to DOS
    mov ax, 4c00h
    int 21h
main ENDP

; Place the interrupt data in the code segment instead of the data segment
; to simplify the interrupt handler

int1c_old_ofs dw 0              ; Offset of original int 1c vector
int1c_old_seg dw 0              ; Segment of original int 1c vector
timer_tick    dw 0              ; Timer tick count (incremented 18.2 times a second)

END main

Note:由于此代码是在 DOS 下假设编写的,因此我使用 DOS 服务国际21小时/AH=35小时 http://www.ctyme.com/intr/rb-2740.htm(DOS获取当前中断向量)和国际21小时/AH=25小时 http://www.ctyme.com/intr/rb-2602.htm(DOS设置中断向量)用我们自己的中断向量替换用户定时器中断,然后在返回DOS之前将中断向量恢复到原始状态。您可以通过直接读取/修改实模式中断向量表来替换这些 DOS 调用。在 DOS 下,最好使用 DOS 服务来完成此操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设置定时器 的相关文章

  • 在汇编中显示两位数? [复制]

    这个问题在这里已经有答案了 我对汇编编程完全陌生 在课堂作业的示例中 需要将两个数字相加并显示总和 我发现神秘的是当其是两位数时显示总和 这是我的代码 mov al num1 mov bl num2 add al bl add ax 303
  • 为什么这个“std::atomic_thread_fence”起作用

    首先我想谈一下我对此的一些理解 如有错误请指正 a MFENCE在x86中可以保证全屏障 顺序一致性可防止 STORE STORE STORE LOAD LOAD STORE 和 LOAD LOAD 重新排序 这是根据维基百科 https
  • 一条指令可以同时处于两种寻址模式吗?

    我在书中读到了以下内容从头开始编程 处理器有多种不同的访问数据的方式 称为 寻址模式 最简单的模式是立即模式 其中 要访问的数据嵌入在指令本身中 例如 如果我们想将寄存器初始化为 0 而不是给出 计算机要从中读取 0 的地址 我们将指定立即
  • x86-64 上这个语句有什么问题?

    该函数的目的是获取堆栈的起始地址 unsigned long find start void asm movq rsp eax 当我编译它时 出现错误 Error suffix or operands invalid for movq mo
  • 预取双类成员需要转换为 char*?

    我有一个正在使用的课程 mm prefetch 预先请求包含 double 类型的类成员的缓存行 class MyClass double getDouble return dbl other members double dbl othe
  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • 为什么 SSE 对齐读取 + 随机播放在某些 CPU 上比未对齐读取慢,而在其他 CPU 上则不然?

    在尝试优化有限差分代码所需的未对齐读取时 我更改了未对齐的负载 如下所示 m128 pm1 mm loadu ps H k 1 进入这个对齐的读取 随机播放代码 m128 p0 mm load ps H k m128 pm4 mm load
  • AVX512 掩码寄存器(k1...k7)的 GNU C 内联 asm 输入约束?

    AVX512 为其算术命令引入了 opmask 功能 一个简单的例子 上帝螺栓 org https godbolt org z P7xWD8 include
  • orpd等SSE2指令有什么意义?

    The orpd指令是 压缩双精度浮点值的按位逻辑或 这不是做完 全相同的事情吗por 按位逻辑或 如果是这样 拥有它还有什么意义呢 请记住 SSE1orps https www felixcloutier com x86 orps首先 实
  • 为什么不能执行 mov [eax], [ebx] [重复]

    这个问题在这里已经有答案了 我可以做这个 mov eax ebx 和这个 mov eax ebx 甚至这个 mov eax ebx 但不是这个 错误C2415 mov eax ebx 只是wtf 为什么 它与 ptr1 ptr2 相同 为什
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • 在 x86 Intel VT-X 非根模式下,是否可以在每个指令边界传递中断?

    除了不将中断传送到虚拟处理器的某些正常指定条件 cli if 0 等 之外 客户机中的所有指令实际上都是可中断的吗 也就是说 当传入的硬件中断先传递给 LAPIC 然后传递给处理器时 据说会发生一些内部魔法 将其转换为虚拟中断给来宾 使用虚
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r
  • 从 NASM 调用 C 函数 _printf 会导致分段错误

    我一直在尝试使用 NASM 在 Mac OS 和 Windows 上学习 64 位汇编 我的代码是 extern printf section data msg db Hello World 10 0 section text global
  • 为什么我的空循环在 Intel Skylake CPU 上作为函数调用时运行速度是原来的两倍?

    我正在运行一些测试来比较 C 和 Java 并遇到了一些有趣的事情 在 main 调用的函数中 而不是在 main 本身中 运行具有优化级别 1 O1 的完全相同的基准代码 导致性能大约翻倍 我正在打印 test t 的大小 以毫无疑问地验

随机推荐

  • 如何使用 sqlite3.exe 从导出的 .sql 脚本创建数据库

    尝试将 SqlCe 数据库转换为 SQLite 我将其导出到 sql文件 现在我将如何使用sqlite exe以此创建数据库 sql file 放在哪里sql3 exe file 在 cmd 提示符或在sqlite exe shell 使用
  • Java 数组具有多种数据类型

    我可以使用什么来存储多种不同类型的数据 Int String 等 我有 PHP 背景 我可以将不同类型的数据存储到数组中 但我不知道如何在 Java 中做到这一点 举个例子 array array val1 gt 1 val2 gt cat
  • 是否可以从 PHP 检查 PHP 文件语法?

    我使用自动加载功能动态加载 PHP 类文件 这些文件可能由于某种原因丢失或损坏 自动加载将成功报告丢失的文件 以便应用程序逻辑可以处理该问题 但是 如果这些文件损坏 则整个处理会停止 用户会看到空白屏幕 并且错误日志中会显示 PHP 解析错
  • 尝试获取进程启动时间时“访问被拒绝”

    现在我正在尝试获取计算机上运行的所有进程的启动时间 到目前为止我的代码是这样的 foreach Process item in Process GetProcesses txtActivity AppendText item StartTi
  • 两个自动机之间的等价

    确定两个自动机之间的等价性的最佳或最简单的方法是什么 即 如果给定两个有限自动机 A 和 B 我如何确定两者是否识别相同的语言 它们都是确定性的或都是非确定性的 一种不同的 更简单的方法是对自动机进行补充和交叉 自动机A相当于B iff L
  • 允许同一 COM 库的多个版本

    我编写了一个 C 程序和库 允许用户更轻松地使用特定专有模拟器的 COM 接口 目前 我必须为我希望支持的每个版本的模拟器构建和分发不同版本的 C 库 开发模拟器的公司定期发布新版本 每个新版本都会有一个递增的主版本号 据我所知 版本之间的
  • PHP rtrim 函数修剪多余字符?为什么?

    如何rtrim工作 我有一个字符串 4dbb3dca 我不确定我的字符串是如何格式化的 我想打电话rtrim 4dbb3dca amp edit 可能 amp 特殊字符问题 但是在我的字符串之后4dbb3dc 我希望它是4dbb3dca 有
  • C++开发值得学Eclipse吗

    据我所知 从头开始学习使用 Eclipse 是很困难的 但我会得到诸如快速源代码浏览 调用图 静态代码分析等好处 使用 Eclipse for C CDT 还能带来哪些其他好处 我学习了 C Eclipse 它非常灵活并提供许多功能 我不再
  • 使用两个 1d 数组高效索引 2d numpy 数组

    我有一个大型 2d numpy 数组和两个 1d 数组 表示 2d 数组中的 x y 索引 我想使用这些一维数组对二维数组执行操作 我可以使用 for 循环来完成此操作 但在处理大型数组时速度非常慢 有更快的方法吗 我尝试简单地使用一维数组
  • Scala:隐式传递一个隐式参数,显式传递另一个参数。是否可以?

    让我们考虑一下这个函数 def foo implicit a Int b String println a b 现在 让我们假设有一个隐含的String and Int implicit val i1 1 在范围内 但我们想传递另一个 no
  • 构建器模式与配置对象

    构建器模式在创建不可变对象时很流行 但创建构建器会产生一些编程开销 所以我想知道为什么不简单地使用配置对象 构建器的用法如下所示 Product p Product Builder name Vodka alcohol 0 38 size
  • 如何在Python中创建一组参数化函数? [复制]

    这个问题在这里已经有答案了 我正在尝试创建一系列函数 并通过 shift 参数进行参数化 考虑下面的代码 我希望 for 循环创建一组函数 每个函数都会改变 不同数量的争论 Python 3 code N 5 fns for idx in
  • 如何检查数组中是否可以求和?

    给定一个数组N整数 检查是否可以获得总和S 通过选择数组的一些 或不选择 元素并添加它们 我尝试使用贪婪方法解决这个问题 首先对数组进行排序 然后越来越接近总和 然而它不起作用 谁能告诉我应该如何解决这个问题 t int input for
  • iPhone:NSURLRequest CachePolicy 设置之间的性能差异

    使用时NSURL请求 http developer apple com iphone library documentation Cocoa Reference Foundation Classes NSURLRequest Class R
  • 什么是红/绿测试?

    我相信我已经知道答案 但我不是 100 确定 所以只是一个简单的问题 红 绿测试实际上意味着什么 我将其理解为 首先编写测试 以便它们全部失败 全部红色 然后编写代码并观察每个测试如何变成绿色 当所有测试都变成绿色时 就没事了 我在Scot
  • npm 包中的二进制文件

    我尝试创建一个 npm 包 它可以作为 shell 中的命令启动 我有package json name myapp version 0 0 6 dependencies async watch node promise rmdir sho
  • Java中的内部静态类

    使用内部静态类有什么好处 与其他选项相比 我应该在哪些方面更喜欢它 它的内存是如何分配的 如果内部类是静态的 则不需要外部类的实例来实例化它 如果内部类是公共的 那么它基本上只是一种名称范围技术 用于强调该类 属于 外部类这一事实 但是 如
  • 如何声明对本机 .so 库的依赖以进行测试?

    我在 Akka 中有一个生产应用程序 我从以下选项开始 Djava library path native with native包含库的目录libsigar amd64 linux so 一切都很好 当我打字时sbt test我面临以下错
  • ImageMagick Convert 在命令行中工作,但不能通过 PHP exec()

    我正在使用 PHPexec 使用 ImagicMagick 转换图像convert 这是在 CentOS 服务器上运行的 exec convert http www google com images srpr logo3w png jpg
  • 如何设置定时器

    有什么办法可以将计时器设置为 60 秒xor ah ah Enter Again xor ah ah I should put 60 seconds here int 16h The user should press S before 6