z3萃取物和海螺之间的endian混合

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

我很难理解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.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.