汇编学习笔记(2)

db ;8 bit char
dw;define word double byte short int 16bit
dd define  float or long int 32 bit 
dq;define quadruple word 8 byte 64 bit,double or int of 64bit
dt;define ten bytes 80bit ;long double %LF can not use to define a int 

pi dd 3.14;define a float pi =3.14
x dd 1234567h; long int x=0x1234567
x dq 12345688h; int64 x=0x12345678
 y dq 2.71453414; double y
 ;汇编里面是看具体给出的内容进行识别,如果你给的是个小数,他把当成一个小数
 ;__int64 vc里面专用的define 64 bit int %I64d(十进制)  %I64x(16进制)
 

  • 小端规则:

    • 先存放低8位,后存放高8位

    • short int a =0x1234;
      a dw 1234h
      
      
    • 12为高八位,34为第八位

    • 1000 0x34

    • 1001 0x12

    • (按着指针的顺序,先检索的到的是低8位,与我们习惯相反,所以称为小端规则)

  • 大端规则

    • 先存放高八位,再保存低八位
    • 1000 0x12
    • 1001 0x34
  • intel的机器为小端规则

why choose small-ending

if we long int a=0x12345678

char b=a/b=0x78/

再使用计算机的时候,我们不能明确某个地址指向的内容,除非我们加上类型修饰,这样才可以知道内容的长度

unsigned char  0,255 00h,FFh
unsigned short int 0,65535 00h,ffffh
unsigned long int  00000000h,ffffffffh;
+127
 01111111
    -128
    100000000
  • 零扩充和符号扩充
    • unsigned char a =0xfe
    • short int b;
    • b=a;把a零扩充后赋值给b,b=0x00fe
    • 如果等号右边的数为非符号,那么就使用零扩充
    • 非符号数放大的时候左边永远补零,跟目标(赋值的对象 )的类型无关
    • char a=0xfe;//说明这个是一个补码,是-2.因为有符号,如何知道一个补码是多少,找相反数,使和为0
    • 1111110+00000010=0所以就是-2
    • unsigned short int b;
    • b=a;b=1111111111111110,b=0xffee,因为这里有符号,所以就直接加上1就可以
    • 把一个负数(不管是多少,只要是符号数就补1)进行符号扩充,直接补1就可以,(因为只有补1才能保证原来的符号值没有改变)
  • 小数保存
    • 11.11 小数后面第一位代表2的-1次方,第二个1代表2的负二次方
    • float
      • 32位
      • 0x42fec000
      • 01000010 11111110 11000000 00000000
      • 0 10000101 11111101100000000000000
      • 划分为这三段
      • 最高位的0代表符号位,与之前类似,
      • 后面紧跟的8个位为偏执指数,非符号数,这个值在这里是133,然后减去127这个常数得到6,这个指数就是我们实际的指数,代表2的多少次方
      • 把剩余的23位抄下来,再前面增加一个1.
      • 在这里就是1.11111101100000000000000作为真实的尾数
      • 最后的结果就是把之前的指数与之前的指数相乘
      • 这里就是1111111.01100000000000
      • 算出实际的值
      • 127+1/4+1/8=127.375,而且这个是个正数
      • 由于这里尾数要加上1.的规则,直接规定,如果32位全为0,那么就代表0.0
      • c中char会被自动转化为int
      • unsigend char前面补0,所以看不出来,但对于char来说,前面补1,所以在显示上会有所差异
add;加
sub;减
mul;乘
div;除

;加减乘除运算不可以同时操作两个变量
add a[0],a[1];语法错误,因为操作数不能同时都是内存变量,有硬件的局限,cpu做不到
;正确写法
mov ah,a[1];假设a[0]位一个byte,而ah刚好为一个byte
add a[0],ah;

add ds:[1000h],2;语法错误,因为2的宽度不确定,而左边的宽度也不确定,只能确定这个变量的首地址,不知道这个首地址具体指向的是什么,汇编中在直接运算的时候并没有自动给出变量类型
add byte ptr ds:[1000h],2; ptr pointer, byte ptr可以理解为char * 类似于强制类型转化
add word ptr ds:[1000h],2;wort pointer 相当于short int *
add dword ptr ds:[1000h],2;double word ptr相当于long int *

add a[0],1;ok
add ax,bx;寄存器,寄存器
add ax,2;寄存器,常数
add ax,ds:[1000h];寄存器,内存变量,[]表示偏移地址,ds表示段地址
add ds:[1000h],ax;内存变量,寄存器
add word ptr ds:[1000h],2;汇编语言中,常数是没有宽度的,




;汇编使用的逻辑运算
and or xor not shl(<< shift left) shr(>> shift right)
rol(循环左移 rotate lef ) ror(rotate right循环右移)

mov ah,8fh;10001111
rol ah,1;00011111,循环左移没有0填坑;可逆,不会造成位的丢失,具有可逆性

分析一下思路,

一个

abc dd 12345678h

12345678h,循环左移4位变成23456781h

再把2345 6781h and 0000 000Fh=0000 0001h

再循环左移4次变成34567812h,相当于左移1字节

再and 0000 000Fh=0000 0002h

连续做8次循环,提取到了数字的1,2,3,4,5,6,7,8

相当于是0001,0002,0003,0004,0005,0006,0007,0008

然后手动贴引号,类似于1+‘A’,实际上是asicc码转化

把他保存在数组

s db “12345678”

.386
;将8086和386混合起来使用
data segment use16
abc dd 2147483647;10进制
s db 8 dup(0),0Dh,0Ah,'$'
t dd 0
data ends


code segment use16
assume cs:code,ds:data
main:
	mov ax,data
	mov ds,ax;ds复制位短地址
	mov eax,abc
	
	mov cx,8
	mov di,0;目标数字及s的下表
again:
	rol eax,4;
	push eax;保护eax的值
	and eax,0Fh;这里会把eax的值给毁掉,所以需要在前面先把eax压入堆栈
	cmp al,10
	
is_digit:
	add al,'0'
	jmp finish_4bits
is_alpha:
	sub al,10
	add al,'A'
finish_4bits:
	mov s[di],al
	pop eax;弹出堆栈,可以把eax的值覆盖成堆栈里面存储的eax值,如果用变量来存的话会多定义一个data并且还涉及引用,如果用寄存器的话会浪费一个寄存器,所以我们使用堆栈的方式
	add di,1
	sub cx,1
code ends
end main
  • 段地址与偏移地址
    • 一个数字的地址称为物理地址,:连接的两个数字表示的地址称为逻辑地址
    • 段首地址必须要保证地址16进制的最后一位是0
    • 1个物理地址可能对应着多个逻辑地址
    • 段长度有限制,FFFFh为最大的偏移地址,所以长度为10000h,216次方26k及64k,
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值