- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我问过类似的问题here但是我改变了汇编程序并且问题几乎完全改变了,所以为了避免问题困惑我发布了一个全新的问题。无论如何,长话短说,我在 Windows 7 上,我刚刚安装了 NASM,我正在尝试从 Michael Abrash 的一本名为 Zen of Assembly 的书中汇编代码 list 。这是列表的代码:
;
; *** Listing 2-1 ***
;
; The precision Zen timer (PZTIMER.ASM)
;
; Uses the 8253 timer to time the performance of code that takes
; less than about 54 milliseconds to execute, with a resolution
; of better than 10 microseconds.
;
; By Michael Abrash 4/26/89
;
; Externally callable routines:
;
; ZTimerOn: Starts the Zen timer, with interrupts disabled.
;
; ZTimerOff: Stops the Zen timer, saves the timer count,
; times the overhead code, and restores interrupts to the
; state they were in when ZTimerOn was called.
;
; ZTimerReport: Prints the net time that passed between starting
; and stopping the timer.
;
; Note: If longer than about 54 ms passes between ZTimerOn and
; ZTimerOff calls, the timer turns over and the count is
; inaccurate. When this happens, an error message is displayed
; instead of a count. The long-period Zen timer should be used
; in such cases.
;
; Note: Interrupts *MUST* be left off between calls to ZTimerOn
; and ZTimerOff for accurate timing and for detection of
; timer overflow.
;
; Note: These routines can introduce slight inaccuracies into the
; system clock count for each code section timed even if
; timer 0 doesn't overflow. If timer 0 does overflow, the
; system clock can become slow by virtually any amount of
; time, since the system clock can't advance while the
; precison timer is timing. Consequently, it's a good idea
; to reboot at the end of each timing session. (The
; battery-backed clock, if any, is not affected by the Zen
; timer.)
;
; All registers, and all flags except the interrupt flag, are
; preserved by all routines. Interrupts are enabled and then disabled
; by ZTimerOn, and are restored by ZTimerOff to the state they were
; in when ZTimerOn was called.
;
Code segment word public 'CODE'
assume cs:Code, ds:nothing
public ZTimerOn, ZTimerOff, ZTimerReport
;
; Base address of the 8253 timer chip.
;
BASE_8253 equ 40h
;
; The address of the timer 0 count registers in the 8253.
;
TIMER_0_8253 equ BASE_8253 + 0
;
; The address of the mode register in the 8253.
;
MODE_8253 equ BASE_8253 + 3
;
; The address of Operation Command Word 3 in the 8259 Programmable
; Interrupt Controller (PIC) (write only, and writable only when
; bit 4 of the byte written to this address is 0 and bit 3 is 1).
;
OCW3 equ 20h
;
; The address of the Interrupt Request register in the 8259 PIC
; (read only, and readable only when bit 1 of OCW3 = 1 and bit 0
; of OCW3 = 0).
;
IRR equ 20h
;
; Macro to emulate a POPF instruction in order to fix the bug in some
; 80286 chips which allows interrupts to occur during a POPF even when
; interrupts remain disabled.
;
MPOPF macro
local p1, p2
jmp short p2
p1: iret ;jump to pushed address & pop flags
p2: push cs ;construct far return address to
call p1 ; the next instruction
endm
;
; Macro to delay briefly to ensure that enough time has elapsed
; between successive I/O accesses so that the device being accessed
; can respond to both accesses even on a very fast PC.
;
DELAY macro
jmp $+2
jmp $+2
jmp $+2
endm
OriginalFlags db ? ;storage for upper byte of
; FLAGS register when
; ZTimerOn called
TimedCount dw ? ;timer 0 count when the timer
; is stopped
ReferenceCount dw ? ;number of counts required to
; execute timer overhead code
OverflowFlag db ? ;used to indicate whether the
; timer overflowed during the
; timing interval
;
; String printed to report results.
;
OutputStr label byte
db 0dh, 0ah, 'Timed count: ', 5 dup (?)
ASCIICountEnd label byte
db ' microseconds', 0dh, 0ah
db '$'
;
; String printed to report timer overflow.
;
OverflowStr label byte
db 0dh, 0ah
db '****************************************************'
db 0dh, 0ah
db '* The timer overflowed, so the interval timed was *'
db 0dh, 0ah
db '* too long for the precision timer to measure. *'
db 0dh, 0ah
db '* Please perform the timing test again with the *'
db 0dh, 0ah
db '* long-period timer. *'
db 0dh, 0ah
db '****************************************************'
db 0dh, 0ah
db '$'
;********************************************************************
;* Routine called to start timing. *
;********************************************************************
ZTimerOn proc near
;
; Save the context of the program being timed.
;
push ax
pushf
pop ax ;get flags so we can keep
; interrupts off when leaving
; this routine
mov cs:[OriginalFlags],ah ;remember the state of the
; Interrupt flag
and ah,0fdh ;set pushed interrupt flag
; to 0
push ax
;
; Turn on interrupts, so the timer interrupt can occur if it's
; pending.
;
sti
;
; Set timer 0 of the 8253 to mode 2 (divide-by-N), to cause
; linear counting rather than count-by-two counting. Also
; leaves the 8253 waiting for the initial timer 0 count to
; be loaded.
;
mov al,00110100b ;mode 2
out MODE_8253,al
;
; Set the timer count to 0, so we know we won't get another
; timer interrupt right away.
; Note: this introduces an inaccuracy of up to 54 ms in the system
; clock count each time it is executed.
;
DELAY
sub al,al
out TIMER_0_8253,al ;lsb
DELAY
out TIMER_0_8253,al ;msb
;
; Wait before clearing interrupts to allow the interrupt generated
; when switching from mode 3 to mode 2 to be recognized. The delay
; must be at least 210 ns long to allow time for that interrupt to
; occur. Here, 10 jumps are used for the delay to ensure that the
; delay time will be more than long enough even on a very fast PC.
;
rept 10
jmp $+2
endm
;
; Disable interrupts to get an accurate count.
;
cli
;
; Set the timer count to 0 again to start the timing interval.
;
mov al,00110100b ;set up to load initial
out MODE_8253,al ; timer count
DELAY
sub al,al
out TIMER_0_8253,al ;load count lsb
DELAY
out TIMER_0_8253,al ;load count msb
;
; Restore the context and return.
;
MPOPF ;keeps interrupts off
pop ax
ret
ZTimerOn endp
;********************************************************************
;* Routine called to stop timing and get count. *
;********************************************************************
ZTimerOff proc near
;
; Save the context of the program being timed.
;
push ax
push cx
pushf
;
; Latch the count.
;
mov al,00000000b ;latch timer 0
out MODE_8253,al
;
; See if the timer has overflowed by checking the 8259 for a pending
; timer interrupt.
;
mov al,00001010b ;OCW3, set up to read
out OCW3,al ; Interrupt Request register
DELAY
in al,IRR ;read Interrupt Request
; register
and al,1 ;set AL to 1 if IRQ0 (the
; timer interrupt) is pending
mov cs:[OverflowFlag],al ;store the timer overflow
; status
;
; Allow interrupts to happen again.
;
sti
;
; Read out the count we latched earlier.
;
in al,TIMER_0_8253 ;least significant byte
DELAY
mov ah,al
in al,TIMER_0_8253 ;most significant byte
xchg ah,al
neg ax ;convert from countdown
; remaining to elapsed
; count
mov cs:[TimedCount],ax
; Time a zero-length code fragment, to get a reference for how
; much overhead this routine has. Time it 16 times and average it,
; for accuracy, rounding the result.
;
mov cs:[ReferenceCount],0
mov cx,16
cli ;interrupts off to allow a
; precise reference count
RefLoop:
call ReferenceZTimerOn
call ReferenceZTimerOff
loop RefLoop
sti
add cs:[ReferenceCount],8 ;total + (0.5 * 16)
mov cl,4
shr cs:[ReferenceCount],cl ;(total) / 16 + 0.5
;
; Restore original interrupt state.
;
pop ax ;retrieve flags when called
mov ch,cs:[OriginalFlags] ;get back the original upper
; byte of the FLAGS register
and ch,not 0fdh ;only care about original
; interrupt flag...
and ah,0fdh ;...keep all other flags in
; their current condition
or ah,ch ;make flags word with original
; interrupt flag
push ax ;prepare flags to be popped
;
; Restore the context of the program being timed and return to it.
;
MPOPF ;restore the flags with the
; original interrupt state
pop cx
pop ax
ret
ZTimerOff endp
;
; Called by ZTimerOff to start timer for overhead measurements.
;
ReferenceZTimerOn proc near
;
; Save the context of the program being timed.
;
push ax
pushf ;interrupts are already off
;
; Set timer 0 of the 8253 to mode 2 (divide-by-N), to cause
; linear counting rather than count-by-two counting.
;
mov al,00110100b ;set up to load
out MODE_8253,al ; initial timer count
DELAY
;
; Set the timer count to 0.
;
sub al,al
out TIMER_0_8253,al ;load count lsb
DELAY
out TIMER_0_8253,al ;load count msb
;
; Restore the context of the program being timed and return to it.
;
MPOPF
pop ax
ret
ReferenceZTimerOn endp
;
; Called by ZTimerOff to stop timer and add result to ReferenceCount
; for overhead measurements.
;
ReferenceZTimerOff proc near
;
; Save the context of the program being timed.
;
push ax
push cx
pushf
;
; Latch the count and read it.
;
mov al,00000000b ;latch timer 0
out MODE_8253,al
DELAY
in al,TIMER_0_8253 ;lsb
DELAY
mov ah,al
in al,TIMER_0_8253 ;msb
xchg ah,al
neg ax ;convert from countdown
; remaining to amount
; counted down
add cs:[ReferenceCount],ax
;
; Restore the context of the program being timed and return to it.
;
MPOPF
pop cx
pop ax
ret
ReferenceZTimerOff endp
;********************************************************************
;* Routine called to report timing results. *
;********************************************************************
ZTimerReport proc near
pushf
push ax
push bx
push cx
push dx
push si
push ds
;
push cs ;DOS functions require that DS point
pop ds ; to text to be displayed on the screen
assume ds:Code
;
; Check for timer 0 overflow.
;
cmp [OverflowFlag],0
jz PrintGoodCount
mov dx,offset OverflowStr
mov ah,9
int 21h
jmp short EndZTimerReport
;
; Convert net count to decimal ASCII in microseconds.
;
PrintGoodCount:
mov ax,[TimedCount]
sub ax,[ReferenceCount]
mov si,offset ASCIICountEnd - 1
;
; Convert count to microseconds by multiplying by .8381.
;
mov dx,8381
mul dx
mov bx,10000
div bx ;* .8381 = * 8381 / 10000
;
; Convert time in microseconds to 5 decimal ASCII digits.
;
mov bx,10
mov cx,5
CTSLoop:
sub dx,dx
div bx
add dl,'0'
mov [si],dl
dec si
loop CTSLoop
;
; Print the results.
;
mov ah,9
mov dx,offset OutputStr
int 21h
;
EndZTimerReport:
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
MPOPF
ret
ZTimerReport endp
Code ends
end
我将 nasm.exe 添加到我的路径中,将此文件另存为 listing1.asm,并尝试使用以下 CMD 命令对其进行汇编:
nasm -f win32 listing1.asm
但是,它没有组装,而是给了我以下错误:
listing1.asm:50: error: parser: instruction expected
listing1.asm:51: error: parser: instruction expected
listing1.asm:82: error: parser: instruction expected
listing1.asm:83: error: parser: instruction expected
listing1.asm:95: error: parser: instruction expected
listing1.asm:99: error: symbol `endm' redefined
listing1.asm:114: error: parser: instruction expected
listing1.asm:115: error: comma expected after operand 4
listing1.asm:116: error: parser: instruction expected
listing1.asm:122: error: parser: instruction expected
listing1.asm:142: error: parser: instruction expected
listing1.asm:176: error: symbol `DELAY' redefined
listing1.asm:179: error: symbol `DELAY' redefined
listing1.asm:188: error: parser: instruction expected
listing1.asm:190: error: symbol `endm' redefined
listing1.asm:200: error: symbol `DELAY' redefined
listing1.asm:203: error: symbol `DELAY' redefined
listing1.asm:208: error: symbol `MPOPF' redefined
listing1.asm:212: error: symbol `ZTimerOn' redefined
listing1.asm:212: error: parser: instruction expected
listing1.asm:218: error: parser: instruction expected
listing1.asm:237: error: symbol `DELAY' redefined
listing1.asm:252: error: symbol `DELAY' redefined
listing1.asm:282: error: comma, colon or end of line expected
listing1.asm:292: error: symbol `MPOPF' redefined
listing1.asm:298: error: symbol `ZTimerOff' redefined
listing1.asm:298: error: parser: instruction expected
listing1.asm:304: error: parser: instruction expected
listing1.asm:316: error: symbol `DELAY' redefined
listing1.asm:322: error: symbol `DELAY' redefined
listing1.asm:327: error: symbol `MPOPF' redefined
listing1.asm:331: error: symbol `ReferenceZTimerOn' redefined
listing1.asm:331: error: parser: instruction expected
listing1.asm:338: error: parser: instruction expected
listing1.asm:350: error: symbol `DELAY' redefined
listing1.asm:352: error: symbol `DELAY' redefined
listing1.asm:363: error: symbol `MPOPF' redefined
listing1.asm:368: error: symbol `ReferenceZTimerOff' redefined
listing1.asm:368: error: parser: instruction expected
listing1.asm:374: error: parser: instruction expected
listing1.asm:386: error: symbol `assume' redefined
listing1.asm:386: error: parser: instruction expected
listing1.asm:392: error: comma, colon or end of line expected
listing1.asm:402: error: comma, colon or end of line expected
listing1.asm:426: error: comma, colon or end of line expected
listing1.asm:436: error: symbol `MPOPF' redefined
listing1.asm:439: error: symbol `ZTimerReport' redefined
listing1.asm:439: error: parser: instruction expected
listing1.asm:441: error: symbol `Code' redefined
listing1.asm:441: error: parser: instruction expected
不确定我应该在这里做什么;我试过用谷歌搜索一下,但没有找到任何东西。有人认出这些错误吗?
最佳答案
那个汇编语言是 MASM,不是 NASM。
对于初学者来说,NASM 段的定义不同。
代替
Code segment word public 'CODE'
我们写
.section text
还有那个“ASSUME”声明……你一定有一本古老的书。那是旧的、旧的 MASM 代码。让我想起了 80 年代初的记忆!
NASM 和 MASM 之间有很多差异,您的代码需要大量工作才能移植。如果您想将该 MASM 代码移植到 NASM,请参阅 MASM/NASM Differences或 NASM 文档或谷歌“NASM vs MASM”
TL;DR:您正在编写 MASM 代码,而不是 NASM。
关于assembly - NASM 错误解析,预期指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11572307/
我刚刚在学习 NASM,我有点想弄清楚这个问题。你如何在 NASM 中声明变量?例如,如何在 NASM 中声明 unsigned int i?谢谢 最佳答案 汇编语言中没有 unsigned int
我正在阅读这篇关于操作系统编程的精彩脚本 http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 第 12 页有一
我正在尝试使用 nasm 打印给我的程序的命令行参数: GLOBAL main EXTERN printf section .rodata fmt db "Argument: %s", 10, 0 s
这两种工具都将汇编指令直接翻译成机器代码,但是否有可能确定哪一种产生最快和最干净的代码? 最佳答案 当您使用汇编程序编写时,您准确地描述了生成 的说明所以它不依赖于汇编程序。这取决于你。您编写的助记符
代码: %define x 0x03 x equ 0x03 它们之间有什么区别? 最佳答案 %define是一种更强大的宏处理方式,类似于 C 预处理器。在您的简单情况下,使用 x 没有太大区
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 8 年前。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。更详细地描述您的问题或inclu
我目前正在关注 a tutorial on OS development ,其中包括对引导加载程序的讨论。 我的引导加载程序当前处于 16 位实模式,因此,我能够使用提供的 BIOS 中断(例如 VG
len: equ 2 len: db 2 它们是否相同,产生的标签可以代替2使用?如果不是,那么每种声明形式的优点或缺点是什么?它们可以互换使用吗? 最佳答案 第一个是equate,类似于C
我的循环有问题,其中包含的代码很长,它给了我错误“短跳超出范围”,所以我想知道是否有一种方法可以通过不减少来使循环工作其中代码量有多少? 示例1: label: my code LOOP la
在阅读了至少约4本关于汇编编程的不同书籍的前3或4章之后,我进入了一个阶段,可以使用MASM 6.11将“Hello World”放置在dosbox控制台上。想象一下我的喜悦! 我程序的第一个版本使用
我正在做一个项目,将我编写的子程序附加到老师包含的主文件中。他给了我们使我们的子程序成为全局性的说明,但显然我是个白痴。这两个 asm 文件在同一个文件夹中,我正在使用 nasm -f elf -g
我最近开始使用 NASM 程序集编写代码,但我的问题是我不知道如何以正确的方式访问结构元素。我已经在这个网站和谷歌上搜索了解决方案,但我看到到处都有人说不同的话。我的程序崩溃了,我感觉问题出在访问结构
我正在尝试从用户那里获取输入,然后我想根据用户输入的内容输出一些文本。 我的问题是出于某种原因,它总是认为它是 A,我不知道为什么。你可以在下面找到我的代码: bits 16
我熟悉 TASM 但不太熟悉 NASM。我读过 NASM 允许使用本地标签,这些标签在名称前用点表示。例如代码 .loop: ;some code jmp .loop 定义一个局部标号,
您将如何在寄存器上对 NASM 进行位移?我读了手册,似乎只提到了这些运算符 >> , > 和 >仅用于整数常量。这就是“标量值”的含义。您可以使用 shl 移位寄存器中的值或 shr指示。它们用于将
首先,这是一个家庭作业。 我有一个循环来分别获取两位数的值,并通过将第一个数字乘以 10 并与第二个数字相加得到一个整数来加入它们。 我正在做这一切并保存在我的AL注册,现在我想将该整数插入一个数组,
我一直在做基本的 NASM 编码,我想知道是否可以使用 NASM 模拟按键。如果是这样,怎么做? 如果重要的话,我正在使用 Ubuntu linux 10.04 和 Pentium R T4300 处
我可以在 NASM 中创建一个新标签,它指向一个新的内存位置,该位置与另一个标签指向的内存位置偏移几个字节。 例如:如果 label1 指向内存位置 0x40h,有没有办法使用 label1 定义指向
我需要设置一些标签地址/偏移量的最高位。 我试过: 测试.nasm: BITS 32 dw mylabel | 0x8000 mylabel: dd 0 但是当我尝试组装它时,我得到: nasm -f
如果能向我解释以下使用 printf、使用 nasm 和 gcc 编译的示例中发生了什么,我将不胜感激。为什么“sud”只打印在屏幕上?我也不明白,当我将“push 'sud'”与“push 'sud
我是一名优秀的程序员,十分优秀!