【问题标题】:Does EMU8086 have a bug, or have I made a mistake writing this code?EMU8086 是否有错误,或者我在编写此代码时出错了?
【发布时间】:2016-04-21 14:43:02
【问题描述】:

我尝试做一个练习,我必须在 20 个元素向量中写入斐波那契数列的前 20 个数字,但我不明白为什么代码不能正常工作。它适用于该系列的前 10 个元素,但随后出现了一些我无法识别的问题。你怎么看?这是我写的代码:

DIM EQU 20
COUNT EQU 18
.model small
.stack
.data

 vect dw DIM dup ?

.code
.startup

mov ax,1
mov bx,1
mov cx,COUNT

lea si,vect

mov [si],1
add si,2

ciclo: mov [si],bx
       mov dx,bx
       add bx,ax
       mov ax,dx
       add si,2
       LOOP ciclo

 .exit
 end

更新

我没有完全按照我的程序中显示的方式粘贴代码。我正在运行的程序开始于:

ORG 100h

我不认为这很重要,所以我把它省略了。重要吗?

这是我在调试原始代码时看到的。我走到ciclo: mov [si],bxCX 里面有 8 个。

当我单步执行时,程序退出并显示PROGRAM HAS RETURNED CONTROL TO THE OPERATING SYSTEM,如下图所示:

为什么会这样?

【问题讨论】:

  • 请提供比“有一些我无法识别的问题”更详细的问题描述。
  • 你的模拟器没有问题。
  • 是的,这是一个复制/粘贴错误。关于“mov [si],1”这一行,如果我没记错的话,英特尔使用小端序,指定 1 的大小更正确,但并不那么重要。无论如何感谢您的帮助,现在我要发布两个屏幕截图,因为我在调试过程中发现了一些奇怪的东西。如果您仍然想帮助我,我将不胜感激。

标签: assembly x86-16 emu8086


【解决方案1】:

你的代码失败的原因是你的原始代码在顶部有这个:

ORG 100h

在 EMU8086 中,这具有将程序创建为 DOS COM 程序(不是 DOS EXE 程序)的副作用。使用 COM 程序 - 如果您将数据放在代码之前,它将开始将您的 DATA 作为代码执行。在您的情况下,它开始在您的 vect 数组中执行垃圾,然后尝试(未成功)运行您的实际代码。这就是您的程序在运行和通过 EMU8086 调试时表现出的所有奇怪行为的原因。

因为您显然有一个数据区,而堆栈只需从顶部删除 org 100h,这将允许 EMU8086 将您的代码作为 DOS EXE 而不是 DOS COM 程序执行。


如果要创建 DOS COM 程序,则需要删除 .stack 指令。将data 段移到最后一段可执行代码之后,在这种情况下,就是.exit 创建的代码。这可确保当 DOS 在顶部启动您的程序时,DATA 不会作为代码执行。这不是 EMU8086 中的 DOS EXE 程序的问题。

DIM EQU 20
COUNT EQU 18 

org 100h             ; COM programs are placed 256 from beginning of
                     ; of segment so we need ORG 100h. This
                     ; also informs EMU8086 you want to make a COM program
                     ; and not an EXE program.

                     ; No Stack specified for a COM program as DOS
                     ; automatically places it at the top of the 64K segment
                     ; and grows downward toward the code and data.

.model tiny          ; Normally COM programs are TINY model (CS=DS=SS) 

.code
.startup             ; This isn't needed for COM programs but won't hurt.

mov ax,1
mov bx,1
mov cx,COUNT

lea si,vect

mov word ptr [si],1 ; To avoid a bug we want to update the WORD at [si]
                    ; not the BYTE.
add si,2


ciclo: mov [si],bx
       mov dx,bx
       add bx,ax
       mov ax,dx
       add si,2
       LOOP ciclo
       .exit        ; Program exits here

.data               ; Place the data after the code for a COM program

 vect dw DIM dup ?

end

【讨论】:

    【解决方案2】:

    我在 EMU8086 中测试了你的代码,发现了两个小错误:code 之前的点和初始化数据段。这是您的代码修复:

    DIM EQU 20
    COUNT EQU 18
    .model small
    .stack
    .data
    
     vect dw DIM dup ?
    
    .code                          ;<=================================
    .startup
    mov ax, @data                  ;<=================================
    mov ds, ax                     ;<=================================
    
    mov ax,1
    mov bx,1
    mov cx,COUNT
    
    lea si,vect
    
    mov [si],1
    add si,2
    
    ciclo: mov [si],bx
           mov dx,bx
           add bx,ax
           mov ax,dx
           add si,2
           LOOP ciclo
    
     .exit
     end
    

    下一个屏幕截图证明,通过修复程序运行良好(见右下角的斐波那契数字?):

    【讨论】:

    • 我不同意你的修复做任何事情(除了缺少的时期)。 .startup 指令将发出代码以适当地设置 DS
    • @MichaelPetch,在我的 EMU8086 中不会发生这种情况,我必须添加这两行才能使其工作。
    • 你用的是什么版本?在 4.08 上,.startup 通过 DX 寄存器生成 movds。可能某些旧版本无法正确执行此操作。
    • 我的是 4.08,.startup 指令发出 2 条指令来更新我的环境中的 DS。这正是 EXE 应该发出的内容是 MASM/TASM/EMU8086。
    • 我没有运行 EXE,但是当模拟器使用 PSP(而不是内部的 COM 程序)生成 EXE 时,它会模拟EXE 环境)。当您打开 EMU8086 时,它会询问您是否要生成 EXE 或 COM,但可以使用文件第一行上的适当 # 指令覆盖或使用 .model tiny 进行更改
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 2020-06-20
    • 2022-01-15
    相关资源
    最近更新 更多