C++逆向——数据存储基础

基本数据类型的表现形式和操作指令

整型

无符号整数

  • 在内存中,无符号整数的所有位都用来表示数值。
  • 当无符号整型不足32位时,用0填充剩余高位,直到占满变量类型的空间。
  • 内存存放数据的方式有两种,小尾存放和大尾存放。小尾存放是以字节为单位,按照数据类型的长度,高数据位对应高地址,低数据位对应低地址。如0x12345678的小尾存放方式为78 65 43 21 ,高尾为 12 34 56 78

有符号整数

  • 有符号整数用来表示正负的是最高位(符号位)。最高位为0表示正数,1为负数
  • 有符号整数的取值范围比无符号整数少1位。如uchar -> 0~255 char -> -128~127
  • 负数在内存中以补码的方式存放,补码的规则为对该数值取反加一

浮点数

  • 浮点数编码转换采用的是IEEE标准。IEEE规定将浮点数编码转换为二进制时分为三个部分(float):符号位(1)、指数(8)、尾数(23)
  • 在进行二进制转换前,需要对浮点数进行科学计数法转换。
  • 大于1的数转换:如 12.25f 转换为二进制时,首先将其转换为 1100.01,整数部分为1100,小数部分为01,小数点向左移动,每移动一次指数加1。移动到除符号位的最高为1处停止,此时为1.10001。
    • 此时各位情况为
      • 符号位:0
      • 指数位:3+127转换为二进制10000010(最高位的1在此表示)
      • 尾数位:10001 000….(不足23位时低位用0补充)
  • 小于1数转换: 如-0.125f的转换。首先将其转换为二进制1.00,指数位 -3
    • 此时各位的情况为
      • 符号位:1
      • 指数位:(-3)+127转换为二进制01111100
      • 尾数位:000…..
  • 如果小数部分转换为二进制时是一个无穷值,如0.3
    • 此时各位的情况为:
    • 符号位:0
    • 指数位:0+127
    • 尾数位:01001100110011001100110,转换成16即进制数为0x3FA66666,内存中显示为66 66 A6 3F,舍弃了部分位数。所以进行IEEE编码会产生误差,将其转换为1.2516582,四舍五入为1.3。因此在比较浮点数是否为0时要进行区间比较而不是精确比较。亦可解释浮点数在于整型做比较时可能产生的错误。
  • doube类型的占用空间为float类型的两倍,因此精度更高。double类型的最高位表示符号,11位指数位,42位尾数位
  • 浮点数常用汇编指令(ST为浮点处理器寄存器)
    指令名称使用格式指令功能
    FLDFLD IN将浮点数IN压入栈ST(0)中。IN(mem 32/64/80)
    FILDFILD IN将整数IN压入栈ST(0)中。
    FLDZFLDZ将0.0压入ST(0)中
    FLD1FLD1将1.0压入ST(0)中
    FSTFST OUTST(0)中的数据以浮点数的形式存入OUT地址中
    FSTPFSTP OUT作用与FST一样,但会执行出栈操作
    FISTFIST OUTST(0)的数据以整数的形式存入OUT中
    FISTPFISTP OUT作用与FIST一样,但会执行出栈操作
    FCOMFCOM IN将IN地址的数据与ST(0)进行实数比较,影响对应标记位
    FTSTFTST比较ST(0)是否为0,影响对应标记位
    FADDFADD IN将IN地址内的数据与ST(0)做加法运算,结果放入ST(0)中
    FADDPFADDP ST(N) ST先将ST(N)的数据与ST(0)做加法运算,N的取值范围为0~7,先执行一次出栈操作,然后将相加结果放入ST(0)
  • 在使用浮点数指令时,都要先利用ST(0)进行运算,当ST(0)中有值时,便会将ST(0)中的数据放入ST(1)中,即压栈操作。8个浮点寄存器都有值的情况下再进行压栈会使栈底(ST(7))的数据丢失

  • 当浮点数作为参数时,无论是float或是double都将传递8个字节的数据

字符和字符串

  • 在C++中,字符的编码分为ASCII和UNICODE。ASCII占用1个字节,UNICODE为两个。
  • C++使用结束符’\0’作为字符串的结束标志,ASCII使用一个’\0’,unicode使用两个’\0’。

地址、指针和引用

  • 地址
    • 在C++中,地址标号使用十六进制表示。
    • 只有变量才存在内处地址,常量(不包括const)没有地址
  • 指针
    • 指针为一种保存地址的数据类型
    • 使用不同的方式读取指针所指的数据会得到不同的结果
  • 引用:
  • 引用表示变量的别名,对引用的操作的即是对变量的操作。引用的本质为指针

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据