1

我有一个关于非常低级的事情的问题。我们正在分析微处理器如何执行简单的汇编程序,我们正在使用逻辑分析仪,所以我有 .law 文件。这是我们使用的代码(在我放置操作码的注释中):

mov ax, 1000
mov ds, ax
mov bx, 2000
mov ax, 0aa

mov cx, 100

petla
    push cx ;51
    mov [bx],al ;8807
    mov ax,[bx] ;8B07
    inc al;FEc0
    pop cx;59
loop ;here goes address

我们在调试程序中编写它,组装并观察输出。这是图像:

http://img805.imageshack.us/img805/241/mikro.png

现在,这是奇怪的(至少对我而言)事情:

Data bus:51 - push cx
Data bus:8807 - mov [bx],al
Data bus:0001 - writing to 1EF6A
Data bus:8B07 - mov ax,[bx]
Data bus AA, address bus:12000 - that is writing al to [bx] (ds - 1000, bx - 2000)

突然间,他将 CX 寄存器中的值写入内存中的某个位置(我怀疑 1EF6A 是 SS:SP 的物理地址)。是不是因为

push CX?

如果是,他为什么在

mov [bx],al

为什么写给 [bx] 的时间这么晚?

我在想应该在推送指令之后立即将值推送到堆栈。

4

1 回答 1

4

(对不起,我还没有足够的代表发表评论,所以我求助于写这个答案。)

@Andna:这是一个 8088,对吧?这就是分析器跟踪中的内存访问是一次一个字节的原因。所以你看到的是 8088 的预取单元的结果,它盲目地从内存中读取指令字节并将它们保存在一个短的(4 字节)预取队列中,希望执行单元以后要使用它们。

由执行单元实际执行的指令产生的数据操作将在一段时间后出现在总线上。这就是为什么写入内存的 CX 值不会在push CX读取指令后立即显示,以及为什么 AL 写入直到读取指令后才会出现在总线上MOV AX,[BX]。这也是为什么在循环结束时(不幸的是,此跟踪快照中没有显示),您会看到循环指令之后的预取单元读取指令。然而,执行单元不会执行那些指令。

您担心预取单元的预读可能产生不良副作用是正确的,但是只有当您处理在预取单元已经从该位置收集先前值之后写入的内存位置时才会出现危险,并且仅当您处理程序执行当前点上方的内存位置时才会发生。如果您曾经处于这种情况,那么您必须在尝试读取新写入的位置之前执行一些操作以使预取队列的内容无效。执行一个JMP将做到这一点。

@Zack:这里没有乱序执行,没有多核或多线程,甚至没有任何缓存。只是少量的盲目的、投机的预取。是的,预取确实使跟踪跟踪比 8085 稍微复杂一些。

于 2012-04-21T23:45:46.333 回答