我有一个关于非常低级别的问题。我们正在分析微处理器如何执行简单的汇编程序,我们使用逻辑分析器,所以我有.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]这么晚才发生?
我在考虑在推送指令之后立即将值推送到堆栈。
答案 0 :(得分:4)
(对不起,我还没有足够的代表发表评论,所以我正在写这个答案。)
@Andna:这是8088,对吗?这就是为什么分析仪跟踪中的内存访问是一次一个字节的原因。所以你所看到的是8088的预取单元的结果,该单元盲目地从存储器读取指令字节并将它们保存在一个短的(4字节)预取队列中,希望执行单元以后想要使用它们。执行单元实际执行的指令产生的数据操作将在一段时间后显示在总线上。这就是为什么在读取push CX
指令后,写入存储器的CX值不会立即显示的原因,以及为什么在写入MOV AX,[BX]
指令之后AL写入才会出现在总线上。这也是为什么在循环结束时(遗憾的是未在此跟踪快照中显示),您将看到预取单元读取循环指令之后的指令。但是,执行单元不会执行这些指令。
您可以担心预取单元的预读可能会产生不良副作用,但只有当您处理预取单元已从该位置收集了先前值后写入的内存位置时才会出现危险,这只有在处理当前程序执行点之上的内存位置时才会发生。如果您遇到过这种情况,那么在尝试读取新写入的位置之前,必须先执行某些操作以使预取队列的内容无效。执行JMP
即可。
@Zack:这里没有无序执行,没有多核或多线程,甚至没有任何缓存。只是一小部分盲目的,推测性的预取。是的,预取确实跟踪跟踪比8085更加棘手。