汇编基础
一、数据宽度
数据的高位与低位
数据的右边是低位位,左边是高位,例如:0x1234,34即为低位,12为高位。计算机在存储数据的时候,按照两种方式进行存储高位在前或者低位在前。如图所示,当前的计算机按照高位存储,即将数据的低位存储在寄存器中高位:
数据类型
点击图片可查看完整电子表格
数据在二进制转化为十六进制的过程中,每四位二进制转化为一位十六进制,因此每位十六进制的大小为4bit。
数据在内存中是以二进制形式存储的,int类型占四字节,因此一个int类型数据为32bit,即32个0或者1。
如果一个数据使用char类型变量存储,翻译成汇编则会用byte数据宽度内存来存储
如果一个数据使用short类型变量存储,翻译成汇编则会用word数据宽度内存来存储
如果一个数据使用int类型变量存储,翻译成汇编则会用dword数据宽度内存来存储
使用vc6,查看数据在寄存器中的存储形式,vc中会将输入的数据转化成十六进制。
#include "stdio.h"
void main()
{
int a;
a=12;
printf("%d",a);
}
汇编代码
首先定义一个宽度为4字节即32bit的int形变量,此时需要四个内存地址。
十进制:12
二进制: 00000000 00000000 00000000 00001100
十六进制:0x0C
在存储过程中是从数据的低位向寄存器的高位存储。
如果数据的宽度大于数据类型的宽度,此时数据会被舍弃。
定义一字节大小的char类型,将4bit大小的十进制数字赋值给变量a。
#include "stdio.h"
void main()
{
chr a;
a=1;
printf("%d",a);
}
定义一字节大小的char类型,将8bit即1字节大小的十进制数字赋值给变量a。
#include "stdio.h"
void main()
{
char a;
a=19;
printf("%d",a);
}
定义一字节大小的char类型,将2字节大小的十进制数字赋值给变量a,可以看到数据的宽度大于定义的数据类型宽度,因此首先将数据低位存入寄存器,而高位被舍弃。
#include "stdio.h"
void main()
{
char a;
a=0x1923;
printf("%d",a);
}
二、有符号和无符号
有符号数和无符号数在内存中的存储是一样的。
#include "stdio.h"
void main()
{
short a = 0xff;
unsigned char x = 0xff;
printf("%dn",a);
printf("%d",x);
}
查看汇编,发现无论是有符号还是无符号在内存中都是以FF存储,不分有无符号,在内存中无区别。
类型转化和大小比较
大小比较-有符号
操作系统默认使用有符号即:
#include "stdio.h"
void main()
{
char a = 0xFF;
char x = 0xFF;
if(a>=x)
{
printf("1n");
}else{
printf("0n");
}
printf("%dn",a);
printf("%dn",x);
}
大小比较-无符号
#include "stdio.h"
void main()
{
char a = 0xFF;
unsigned char x = 0xFF;
if(a>=x)
{
printf("1n");
}else{
printf("0n");
}
printf("%dn",a);
printf("%dn",x);
}
大小比较-有符号汇编
大小比较-无符号汇编
无符号:JBE:JUMP SHORT IF BELOW OR EQUAL
有符号:JLE:jump short if less or equal
三、浮点数
类型
float和double类型
float数据类型宽度为32位;double数据类型宽度为64位
小数在内存中的存储
将float类型的12.5转换成16进制
1、将整数部分转化为二进制。
2、将小数部分转化为二进制。
12-->1100
0.5-->1
12.5-->1100.1
3、将得到的二进制数进行左或者右位移,直到小数点移动到第一个有效数字(1)的右边
1100.1左移3位-->1.1001
4、判断正负号。
正数,因此最高位为0。
5、判断位移和位移数。
小数左移动因此30位为1,右移为。
6、左移3位,因此3-1=2。
指数部分为10。
因此最后为
0100 0001 0100 1000 0000 0000 0000 0000
十六进制为0x41480000
将float类型的-12.5转换成16进制
只需修改符号位
0100 0001 0100 1000 0000 0000 0000 0000
十六进制为0x41480000
将float类型的0.25转化为16进制
四、空函数
参数的传递是在函数外部执行的,而不是函数内部。
使用汇编编写函数
#include "stdio.h"
int __declspec(naked) Function(int x,int y,int z)
{
__asm ret
}
void main()
{
Function(1,2,3);
}
五、字符的存储
英文字符的存储
使用标准ascii码来存储英文字符,每个英文字符对应一个ascii,一个英文字符在计算机内使用8bit来存储。
注意:标准ascii码表,二进制位的第一位永远是0。
01100001->0x61h->a
#include "stdio.h"
void main()
{
int a = '中';
printf("%s",a);
}
中文字符的存储
八位二进制数,最多能够定义字符的数量为2的8次方,即128个字符。中文字符太多,因此使用两个字节来表示一个中文,即使用16位来表示一个中文。即GB1312编码表。
编码表
+v:获取优惠券
原文始发于微信公众号(土拨鼠的安全屋):逆向学习 | 汇编基础小记
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论