【问题标题】:How does this x86 assembly program work这个 x86 汇编程序是如何工作的
【发布时间】:2016-01-20 21:12:14
【问题描述】:

这是一个 x86 asm 程序,它在屏幕中间打印一个从 000 到 999 的“计数器”,效果很好(我没有写)。问题是我试图了解它是如何工作的。 DIV 和 STACK 在 THIS 程序中有什么用处。

程序如何知道如何进行,例如从 009 到 010。什么是内循环?

我知道它是如何清屏并打印到屏幕中间的,我知道时钟延迟功能。

DIVPUSHPOP 在此程序中的用途是什么?

基本上我正在尝试跟踪它并了解所使用的功能。我还是一个初学者,请帮助。谢谢。
代码如下:

.MODEL SMALL
.STACK 64
.DATA
CNT DW 0h
.CODE
MOV AX,@data
MOV DS,AX

MOV AX, 0600H
MOV BH,07
MOV CX, 0000
MOV DH,12
MOV DL,39       

INT 10H

MOV AX,0600H
MOV BH,07 
MOV CX,0000 
MOV DX,184FH
INT 10H         

MOV CNT,0

L1: MOV AH,02h
MOV BH,0
MOV DH,12
MOV DL,39
INT 10h         

MOV AX,CNT
MOV BL,10
DIV BL              
PUSH AX

MOV AH,00
MOV BL,10
DIV BL                
PUSH AX               
MOV DL,AL
ADD DL,48
MOV AH,02h
INT 21h

POP AX
MOV DL,AH
ADD DL,48       
MOV AH,02h
INT 21h

POP AX
MOV DL,AH
ADD DL,48
MOV AH,02h      
INT 21h             

MOV CX, 0007h
MOV DX, 2120h 
MOV AH, 86H         
INT 15H             

INC CNT
CMP CNT,999
JBE L1  

MOV AH,4ch          
INT 21h
END

【问题讨论】:

  • JBE L1 是一个跳转指令,使执行在L1: MOV AH,02h处继续进行
  • 使用调试器单步调试代码可能会大大提高您对这段代码的作用和原因的理解程度。

标签: assembly x86 tasm


【解决方案1】:

程序如何知道如何进行,例如从009到010,内循环是什么?

内部循环是从L1 标签到JBE L1 指令形成的。内存CNT 保存正在显示的计数器。它从可执行文件初始化为零并递增 (INC CNT),与 999 相比,当它低于或等于时循环。

DIV、PUSH 和 POP 在这个程序中的作用是什么?

目的是将CNT 值拆分为单独的数字并显示它们。 DIV BLAX 除以BL 并将商存储在AL 中,余数存储在AH 中。

也许最好的解释是通过一个例子。假设CNT 的值为 123。要计算每个可打印的数字,我们将除以 10 并得到 12 余数为 3 的商。现在,我们需要最后打印 3,因此我们需要存储它在堆栈中。然后我们将重复这个过程,得到 2,然后是 1。现在,我们可以打印出 1,从堆栈中弹出 2 并打印它,然后弹出 3 并打印它,这样我们就打印出了 123。

代码段

MOV DL,AH
ADD DL,48       
MOV AH,02h
INT 21h

负责打印每个数字。它首先获取存储在AH 中的余数,加上 48 (030h) 得到 ASCII 数字('0' = 30h .. '9' = 39h),然后调用函数 02h/int21 打印单个字符到屏幕。

【讨论】:

  • 谢谢,你让它更容易理解了
【解决方案2】:

这个指令:

.STACK 64               // reserve a 64 bytes "stack space" for temp data

这条指令:

DIV BL                  // divide the contents of register ax by register bl

由于它们是除以 10,我假设这是将每个数字分开以显示它。

循环在这里:

INC CNT                 // increment (add 1 to) variable CNT (in .DATA)
CMP CNT,999             // compare CNT and 999
JBE L1                  // Jump Below or Equal (to label 'L1')

顺便说一句,你没有问的一点代码是这样的:

MOV CX, 0007h           // high bytes of wait time \__ microseconds
MOV DX, 2120h           // low bytes of wait time  /   (this is ~0.47 secs)
MOV AH, 86H             //
INT 15H                 // INT 15H/86H is wait ("sleep")

【讨论】:

    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    相关资源
    最近更新 更多