我很难理解endian-ness在Z3位向量中是如何工作的。它是否与底层CPU相关联?我正在使用intel cpu,并且Extract看起来像正常预期的那样工作,但是当Concat表示这些值时,endian-ness似乎正好相反。例如,Concat(0xaa,0xbb)产生0xaabb而不是预期的0xbbaa(小端,0xaa在左边,所以应该是最小的)
以下代码说明了我遇到的问题:
import z3
# running on intel os x, little-endian
s = z3.BitVecVal(0xbbaa, 16)
print( "s {}".format(hex(z3.simplify(s).as_long())) ) # 0xbbaa
# b1 and b2 are extracted little-endian, as expected
b1 = z3.Extract(7, 0, s)
b2 = z3.Extract(15, 8, s)
# 0xaa, first byte, smallest
print( "b1 {}".format(hex(z3.simplify(b1).as_long())) )
# 0xbb, second byte, biggest
print( "b2 {}".format(hex(z3.simplify(b2).as_long())) )
# don't understand what is happening here, b1 is the left-most byte,
# should be smallest
j = z3.Concat(b1, b2)
print( "j {}".format(hex(z3.simplify(j).as_long())) )
# result 0xaabb position of bytes are reversed,
# b2 (0xbb) is now smallest
答案 0 :(得分:1)
Z3简单地遵循这里的位向量SMTLib标准,这与架构无关。有关详细信息,请参阅此处:http://smtlib.cs.uiowa.edu/theories-FixedSizeBitVectors.shtml
特别是,concat
定义如下:
[[(concat s t)]] := λx:[0, n+m). if (x < m) then [[t]](x) else [[s]](x - m)
where
s and t are terms of sort (_ BitVec n) and (_ BitVec m), respectively,
0 < n, 0 < m.
这有点拗口,但是如果你仔细研究它,语义清楚地表明&#34;更低&#34;零件来自t
和&#34;鞋帮&#34;部分来自s
。
同样,extract
定义为:
[[((_ extract i j) s))]] := λx:[0, i-j+1). [[s]](j + x)
where s is of sort (_ BitVec l), 0 ≤ j ≤ i < l.
基本上会丢弃第一个j-1
位并保持从那时开始的i
位。
答案 1 :(得分:0)
好的,我想我已经弄明白了。它在任何地方都没有很好的记录,但z3是big-endian。位总是从右边开始索引,0是最右边的最小位。这解释了Extract(Extract(high,low,from))参数的奇怪顺序,因为“高”位实际上位于低位的左侧。
Concat和Extract似乎具有不同的endianess,因为从右到左提取切片,Concat从左到右构建位向量。