Jche
qwqqqqqq

符号位扩展

2021-12-12 0-1のpython

starts

在做normal5的时候有遇到很多不会的地方,比如为什么要对数据按位与(0xff),补0扩展和符号位扩展有什么用,这些操作和数据的关联。其实类似于这个0xff在level7的时候已经遇到过一次,当时只知道是为了防止数据溢出,当我在对normal5最后flag的数据操作时发现ff的个数会影响最后得到的数据,且对数据的操作顺序改变会导致flag得到不是想要的数据。于是打算好好看一下这个问题。

&

&上一个0xff的起因大概是用一个dword和byte进行了比较,提取数据的时候数据是这样的:

1
0xFFFFFFC4, 0x00000034, 0x00000022, 0xFFFFFFB1, 0xFFFFFFD3, 0x00000011, 0xFFFFFF97, 0x00000007, 0xFFFFFFDB, 0x00000037, 0xFFFFFFC4, 0x00000006, 0x0000001D, 0xFFFFFFFC, 0x0000005B, 0xFFFFFFED, 0xFFFFFF98, 0xFFFFFFDF, 0xFFFFFF94, 0xFFFFFFD8, 0xFFFFFFB3, 0xFFFFFF84, 0xFFFFFFCC, 0x00000008

询问了别人这个0xff是怎么回事,现在大概了解了一些,所谓的高位清零是什么意思。0xff转化为二进制数就是1111111,一共有8个bit,一个字节。&0xff就是使这个数字的低8bit不变,其他的全部清零,因为&的意思就是1&1为1,其他都是0。这样将这个数字&0xff就使低8bit这个byte是1就是1,是0就是0,把高位全部清零,从而可以限制到一个字节的大小。这样一来就可以进行比较了。

movsx / movzx

MOVZX 指令(进行全零扩展并传送)将源操作数复制到目的操作数,并把目的操作数 0 扩展到 16 位或 32 位。这条指令只用于无符号整数。

1
2
3
4
mov bx, 0A69Bh
movzx eax, bx ;EAX = 0000A69Bh
movzx edx, bl ;EDX = 0000009Bh
movzx cx, bl ;CX = 009Bh

MOVSX 指令(进行符号扩展并传送)将源操作数内容复制到目的操作数,并把目的操作数符号扩展到 16 位或 32 位。这条指令只用于有符号整数。(符号位就是0或者1)

1
2
3
4
.data
byteVal BYTE 10001111b
.code
movsx ax,byteVal ;AX = 1111111110001111b

看了别人对normal5的分析,这里对符号位进行扩展的原因是flag里面有负数。输出字符如果是负数那么就没办法转字符了。

去找了一下可以理解符号位扩展的文章,这个例子就比较容易理解:

以-64为例,其8位的二进制补码(1100 0000)表示成十六进制是0xC0,而等效的16位二进制补码(1111 1111 1100 0000)表示成十六进制是0xFFC0,很显然,位模式不一样。再看数+64,其8位二进制补码(0100 0000)和16位二进制补码(0000 0000 0100 0000)表示,分别是0x40与0x0040。事实是,扩展负数的大小与扩展非负数的大小是完全不同的。

处理不同长度的有符号数时,我们必须使用符号扩展。例如,将一个字节量与一个字量相加时,在相加之前,必须将字节量符号扩展到16位,其他运算可能需要符号扩展到32位。

清零和符号位扩展大多用于比较两个长度不同的数据。

END

寄。

Author: John Doe

Link: http://example.com/2021/12/12/movzx-movsz/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
Z3约束求解器
NextPost >
normal归纳
CATALOG
  1. 1. starts
  2. 2. &
  3. 3. movsx / movzx
  4. 4. END