z3萃取物和海螺之间的endian混合
我很难理解endian ness如何在Z3位向量中工作。它是否与底层CPU绑定?我使用的是intel cpu,Extract似乎可以像预期的那样在endian上工作,但是当浓缩这些值时,endian的性质似乎相反。例如,Concat(0xaa,0xbb)生成0xaabb,而不是预期的0xbbaa(小端点,0xaa在左边,所以应该是最小的) 以下代码说明了我遇到的问题:z3萃取物和海螺之间的endian混合,z3,Z3,我很难理解endian ness如何在Z3位向量中工作。它是否与底层CPU绑定?我使用的是intel cpu,Extract似乎可以像预期的那样在endian上工作,但是当浓缩这些值时,endian的性质似乎相反。例如,Concat(0xaa,0xbb)生成0xaabb,而不是预期的0xbbaa(小端点,0xaa在左边,所以应该是最小的) 以下代码说明了我遇到的问题: import z3 # running on intel os x, little-endian s = z3.BitVec
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
好吧,我想我已经弄明白了。它在任何地方都没有很好的记录,但z3是big-endian。位总是从右边索引,0是最右边、最小的位。这就解释了提取参数的奇怪顺序(提取(高、低、自)),因为“高”位实际上位于低位的左侧
Concat和Extract似乎具有不同的endianess,因为从右到左提取切片,Concat从左到右构建位向量。Z3只是遵循SMTLib位向量标准,这与体系结构无关。详情请参见此处: 具体而言,
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.
基本上,它会删除第一个
j-1
位,并从那时起保持到i
th位。所有向量都根据SMT标准进行编码。如果愿意,可以假设所有向量的大端性。extract指令不依赖于endianness,它只是使用与硬件语言(如Verilog和VHDL)相同的索引。感谢与该标准的链接,我不知道它的存在。
[[((_ extract i j) s))]] := λx:[0, i-j+1). [[s]](j + x)
where s is of sort (_ BitVec l), 0 ≤ j ≤ i < l.