Assembly 修改程序集应用程序中的内存

Assembly 修改程序集应用程序中的内存,assembly,x86-16,Assembly,X86 16,我正在学习《x86汇编艺术》一书中的汇编语言,我有一个问题想不出答案 程序如下所示: 在本练习中,您将启动一个正在运行的程序,该程序将检查内存中的值并对其进行操作。然后,您将切换到内存屏幕并修改内存中的值(即,在程序继续运行时,您将直接访问内存) 程序首先将内存位置1000h设置为零,然后循环,直到满足两个条件之一-用户切换FFF0开关或用户更改内存位置1000h中的值。切换FFF0开关终止程序 更改内存位置1000h中的值会将控制转移到程序的一部分,该部分将n个字相加,其中n是内存位置1000

我正在学习《x86汇编艺术》一书中的汇编语言,我有一个问题想不出答案

程序如下所示:

在本练习中,您将启动一个正在运行的程序,该程序将检查内存中的值并对其进行操作。然后,您将切换到内存屏幕并修改内存中的值(即,在程序继续运行时,您将直接访问内存)

程序首先将内存位置1000h设置为零,然后循环,直到满足两个条件之一-用户切换FFF0开关或用户更改内存位置1000h中的值。切换FFF0开关终止程序

更改内存位置1000h中的值会将控制转移到程序的一部分,该部分将n个字相加,其中n是内存位置1000h中的新值。”

在对这些值求和之后,它使用“put”打印它们的和

我有以下代码:

d:  mov cx,0
    mov [1000],cx

a:  mov cx,[1000]
    cmp cx,0
    jne c

    mov ax,[fff0]
    cmp ax,0
    je a
    halt

c:  mov bx,1002
    mov ax,0

b:  add ax,[bx]
    add bx,2
    sub cx,1
    cmp cx,0
    jne b

    put
    jmp d
问题是,当我将12h值设置为1000h时,程序会输出2个值、总和和数字1

当我单步执行程序时,它输出1个值(总和),但当我运行它时,它输出2个值(总和和数字1)


有人能解释一下这种行为吗?

我解释了代码,希望它能帮助一些人:

注意:此代码不考虑多线程或中断更改寄存器。这是一个直接的自上而下的分析(帮助初学者,而不是“专家”)


put
是如何定义的?我不认为这是汇编指令。这个问题似乎离题了,因为它太本地化了。5年内没有答案。不知道你是如何一步一步解决的,无法回答。除非调试器中断了程序,否则运行时应获得与单步执行相同的结果。此外,这个程序是超级臃肿和奇怪的分支。如果您只想在末尾打印一次,为什么在
放置
后会有
jmp
返回顶部?我认为这段代码用于
debug.exe
。它将所有常量视为十六进制,这将解释如何使用
[1000]
然后讨论内存位置
1000h
。其他汇编程序将
1000
视为1000位小数。@PeterCordes debug.exe不支持标签。这是一个相关的问题。看来新的答案相当于
子cx中的巫术专长loltypo,1;bx的Dedict 1
:寄存器错误。这几乎不是一个有用的答案,它根本不跟踪执行情况。另外,标签
a:
处加载的cx=0注释是错误的:它是一个易失性MMIO寄存器或共享变量,不一定要读回存储的内容;程序等待它被修改(由另一个线程或中断处理程序)你想得太多了,这不是为我找工作的帖子(这似乎是这里大多数人都在寻找的-职业发展…?),这并不是假设多线程,等等,这是一个单线程执行,让人来弄明白。仅供参考:我曾经设计过微处理器:)再读一遍这个问题。在异步修改
[1000]
之前,这是一个无限循环,问题具体描述了这一过程。(或者如果
[fff0]
为0,它会立即退出。)(顺便说一句,近十年前发布它的人已经删除了他们的帐户。对于不知道如何阅读单个x86 asm指令的初学者来说,这是一个有用的部分答案,但我怀疑他们中没有多少人会发现这个问题。)是的,在我回答这个问题后,我注意到这个问题已经过时了,我从1991年起就没有编写过核心assm。。。。稍后我将查看问题并编辑答案或将其删除。另外,我只分析了每一行,而不是解决方案,这不是我的本意。欢迎使用Stack Overflow:)我通常通过一次搜索一堆标记来查找要回答的问题,因此我在一个页面上看到这些标记中最近活跃的问题。无论是新问的、编辑的还是回答的。我当前的搜索书签是。
d:  mov cx,0 ; cx = 0
    mov [1000],cx ; Memory address 1000=0

a:  mov cx,[1000] ; Get from memory address 1000 to cx (cx=0)
    cmp cx,0 ; Is cx = 0?
    jne c ; If cx not 0 goto c

    mov ax,[fff0] ; ax = {whatever is at FFF0}
    cmp ax,0 ; Is ax=0?
    je a ; If ax = 0 goto a
    halt ; {STOP PROCESSOR} 

c:  mov bx,1002 ;  BX = 1002
    mov ax,0 ; AX = 0

b:  add ax,[bx] ; Add to ax WHATEVER is in MEMORY location bx
    add bx,2 ; Add 2 to bx
    sub cx,1 ; Deduct 1 from cx
    cmp cx,0 ; is cx = 0?
    jne b ; If cx is not 0 goto b

    put {what do you want to print?}  
    jmp d ; goto d (back to the top)