如果这是重复的问题,请提前道歉。我对以下代码有些困惑:
list db 80h, 70h, 60h, 50h, 40h, 30h, 20h
mov si, offset list
move al,[si]
repit: inc si
add al,[si]
jnc repit
fin:
我知道jnc
表示当没有进位溢出时,即CF = 0
,我们将退出此循环。由于si
应该指向列表第一个元素的索引,所以这不是80h吗?然后,如果si
递增,则应指向70h。将这些加在一起后,答案应该是F0,对吗?但是,当我运行代码块时,我得到的AL值为50。这怎么可能?我想念什么?预先谢谢大家!
答案 0 :(得分:3)
我知道jnc表示当没有进位溢出(即CF = 0)时,我们将退出此循环。
这是不正确的。 JNC
将跳跃,如果CF = 0,则意味着如果没有无符号溢出,它将跳跃。
由于si应该指向列表的第一个元素的索引,所以这不是80h吗?然后,如果si递增,则应指向70h。将这些加在一起后,答案应该是F0,对吗?
到目前为止,是的。
但是,当我运行代码块时,得到的AL值为50。这怎么可能?
我想念什么?
50h的返回值为
80h + 70h + 60h = 50h + CARRY flag (unsigned overflow).
分步进行
80h + 70h = F0h (CF = 0 = JUMP)
F0h + 60h = 50h (CF = 1 = NO JUMP = EXIT LOOP)
由于从FFh到00h(F0h + 0Fh到F0h + 10h(最后是60h-10h = 50h)的无符号溢出,因此最后的加法会将CARRY标志设置为1
。 )。因为设置了CARRY标志,所以有条件的JNC
跳转通过了,并且AL
的确包含了50h的“溢出”值。
答案 1 :(得分:1)
要回答标题问题(与您的其余问题几乎没有关系):
当指定SI指针指向偏移量时,SI指针指向何处?
在x86的分段内存模型中,近指针 是相对于段基的偏移量。 mov si, OFFSET symbol
将SI设置为seg:off
的{{1}}地址的偏移部分。
如果在程序的数据部分中标记了symbol
,并且在symbol
段基=该部分的开始时使用[SI]
,则DS
给出您将[SI]
处的字节用作内存操作数。
SI不会指向偏移量,它会在symbol
之后保持 偏移量。这是指针。
在简单的平面内存模型(如32或64位代码)中,所有内容都使用base = 0,因此offset =线性地址。
在具有“微小”存储模型(例如mov si, OFFSET symbol
)的16位代码中,CS = DS = ES = SS,因此所有存储引用都使用相同的基数。同样,只有16位偏移量可以用作完整的指针。实际的细分受众群是什么都没有关系,因为所有内容都是相对于它的。