1.简介
这一篇文章参考了SPARC Overview,包含简单的进制转换、数据大小、数据对齐到重要的偏移地址计算
《SPARC Overview》:https://download.csdn.net/download/weixin_38987844/12269468
2.准备知识
2.1 进制
需要掌握二进制与十六进制的相互转换以及分别的表示方法,这个就实在没有必要再复制一遍了。这里可以记录一下IDA pro中的一些进制转换的常用快捷键。
在这里面勾选要用到的数据类型,选中数据后可以使用D(DATA)、Q(16进制)、K(变量名)、B(二进制)、C(CODE)、A(ASCII)来转换数据类型
2.2 数据大小与对齐
“Main memory is byte addressable. Addresses are 4 bytes (i.e., 32 bits), allowing for up to 4 gigabytes of memory to be addressed. Every instruction is 4 bytes (i.e., 32 bits) long. Instructions must be word aligned. That is, the their addresses must be divisible by 4.”
即就是说可寻址内存4G,按照4个字节对齐。指令长度是固定的,4个字节,也需要对齐。
“ Halfword, word, and doubleword data must be aligned in memory. For example, a 4 byte word value must be placed at an address that is divisible by 4, and a doubleword must be placed at an address that is divisible by 8. The load and store instructions will cause error exceptions if an attempt is made to move a halfword, word, or doubleword quantity to/from an address that is not properly aligned.”
对齐,这个很重要,不注意对齐算偏移就会算错,偏移算错了就会找错结构体成员,找错成员了反汇编就进行不下去了。对齐就是指x字节的数据存放的起始地址A要满足Amodx=0.举个例子:
typedef struct
{
int a;
double b;
}test;
那么这个结构体的两个成员的起始地址以及结构体的大小在计算时应该要注意对齐。假设test.a的起始地址是0x0,那么test.a在内存中占据了0x0-0x3,下一个字节是0x4,而下一个成员是一个double,8字节,0x4mod0x8!=0。所以应该空4个字节,test.b的起始地址为0x8。那么这个test的大小就为0x8+0x8=0x10。
这个例子比较简单,但是结构体层层嵌套的情况下计算偏移就比较难了,要随时注意对齐。按照道理说此处应该有一个工具用来计算偏移,寻找结构体成员。但是因为懒一直没有写,所以用了更多的时间在手工计算上。下面举一个更进一步的的例子:
typedef union
{
double dd;
int ii;
} union_test;
typedef struct
{
enum e;
union1 u; //start_address = 0x8
int i; //start_address = 0x10
} struct_test; //size = 0x18
这个例子中值得注意的点一个是union的大小是最大的一个成员的大小,另外包含double 的结构体的大小要能模8=0。这就是stuct_test的大小是0x18的原因。
2.3 大小端
SPARC采用大端模式,即高位字节排放在内存低地址,低位字节排放在内存高地址