持续更新,初识汇编_ARM64_001

我们在学习逆向开发之前,我们要了解一个基本的逆向原理.首先我们是逆向iOS系统上面的APP.那么我们知道,一个APP安装在手机上面的可执行文件本质上是二进制文件.因为iPhone手机本质上执行的指令是二进制.是由手机上的CPU执行的.所以逆向开发是建立在分析二进制上面.所以今天我们接下来的课程从非常基础的东西开始讲解.

我们在学习逆向开发之前,我们要了解一个基本的逆向原理.首先我们是逆向iOS系统上面的APP.那么我们知道,一个APP安装在手机上面的可执行文件本质上是二进制文件.因为iPhone手机本质上执行的指令是二进制.是由手机上的CPU执行的.所以逆向开发是建立在分析二进制上面.所以今天我们接下来的课程从非常基础的东西开始讲解.

机器语言,机器语言就是0101组成的世界,计算机通过0101执行指令,但是总不能让程序员写0101吧? 既不好记,可读性又差,且容易出错,所以也就有了汇编语言,汇编语言主要是把特定的语句翻译成0101代码
执行的过程是:程序员->汇编指令->编译器->机器码(0101)->计算机

教材是王爽《汇编语言》第二版

机器语言

由0和1组成的机器指令.

  • 加:0100 0000
  • 减:0100 1000
  • 乘:1111 0111 1110 0000
  • 除:1111 0111 1111 0000

机器语言

由0和1组成的机器指令.

  • 加:0100 0000
  • 减:0100 1000
  • 乘:1111 0111 1110 0000
  • 除:1111 0111 1111 0000

存储器

计算机中最小的存储单元是 bit,也就是一个二进制位
8bit = 1byte(字节)
一个存储单元可以存放1个byte,即8bit,如 0000 1100

第一章 基础知识

  • 机器语言是计算机硬件能直接执行的语言,也就是一系列二进制数字101010101001
  • 汇编语言也是计算机硬件能“间接”执行的语言,他是机器语言更便于程序员书写和记忆的表现形式,所以需要汇编语言到机器语言需要编译器转一下
  • 每一个CPU都有许多管脚,管脚连接着3种总线,分别是地址总线、数据总线和控制总线。3种总线的宽度(也就是总线有多少位)代表了CPU3个方面的性能:
    • 地址总线代表了CPU的寻址能力
    • 数据总线代表了一次能传输的数据量
    • 控制总线负责传输指令
  • 编程中常说的内存其实是假想的逻辑存储空间,他是由一个个真实的物理内存比如RAM、显存、各种接口卡的ROM组成的,再给这个逻辑存储空间从0开始到最大寻址(由地址总线宽度决定)进行编号就有了低地址内存和高地址内存

汇编语言(assembly language)

使用助记符代替机器语言如:

  • 加:INC EAX 通过编译器 0100 0000
  • 减:DEC EAX 通过编译器 0100 1000
  • 乘:MUL EAX 通过编译器 1111 0111 1110 0000
  • 除:DIV EAX 通过编译器 1111 0111 1111 0000

汇编语言(assembly language)

使用助记符代替机器语言如:

  • 加:INC EAX 通过编译器 0100 0000
  • 减:DEC EAX 通过编译器 0100 1000
  • 乘:MUL EAX 通过编译器 1111 0111 1110 0000
  • 除:DIV EAX 通过编译器 1111 0111 1111 0000

CPU对存储器的读写

CPU是通过总线来跟存储器通信的,总线从逻辑上分为地址总线,控制总线,数据总线

  • 地址总线主要是对地址进行传输,每根导线都有低电平和高电平,用二进制来表示就是0和1,10根导线可以传送10位二进制数据,而10位二进制数据有2的10次方的数据组合。

  • 数据总线主要是对数据进行传输,8根数据总线一次可传送8位2进制

  • 控制总线是个总称,控制总线的宽度决定了CPU对外部器件的控制能力

第二章 寄存器

高级语言(High-level programming language)

CC JavaOCSwift,更加接近人类的自然语言比如C语言:

  • 加:A B 通过编译器 0100 0000
  • 减:A-B 通过编译器 0100 1000
  • 乘:A*B 通过编译器 1111 0111 1110 0000
  • 除:A/B 通过编译器 1111 0111 1111 0000

我们的代码在终端设备上是这样的过程:

图片 115193669666308.jpg

  • 汇编语言机器语言一一对应,每一条机器指令都有与之对应的汇编指令
  • 汇编语言可以通过编译得到机器语言机器语言可以通过反汇编得到汇编语言
  • 高级语言可以通过编译得到汇编语言 机器语言,但汇编语言机器语言几乎不可能还原成高级语言

高级语言(High-level programming language)

CC JavaOCSwift,更加接近人类的自然语言比如C语言:

  • 加:A B 通过编译器 0100 0000
  • 减:A-B 通过编译器 0100 1000
  • 乘:A*B 通过编译器 1111 0111 1110 0000
  • 除:A/B 通过编译器 1111 0111 1111 0000

我们的代码在终端设备上是这样的过程:

图片 2

  • 汇编语言机器语言一一对应,每一条机器指令都有与之对应的汇编指令
  • 汇编语言可以通过编译得到机器语言机器语言可以通过反汇编得到汇编语言
  • 高级语言可以通过编译得到汇编语言 机器语言,但汇编语言机器语言几乎不可能还原成高级语言

寄存器

一个典型的CPU由运算器,控制器,寄存器等构成

  • 运算器进行信息处理
  • 寄存器进行信息存储
  • 控制器控制各种器件进行工作
  • 内部总线连接各种器件,在它们之间进行数据传送

1. 通用寄存器:AX,BX,CX,DX

教材中是用的8086CPU,也就是说寄存器是16位的(关于本教材用的8086CPU,地址总线是20位的,数据总线是16位的,内存是8位的),而且为了兼容以前的8位寄存器,这四个寄存器每个都可以拆成高低两个独立寄存器单独使用,所以8086CPU可以读写的数据尺寸有两种,一种是8位的Byte,一种是16位的word(字)

比如,假设此时ax值为005CH,执行语句add al,93H,虽然5CH 93H=158H,但是超出的1并不会存到到ah中去,也就是说此时ax值为0058H,因为此时al是作为一个独立寄存器使用的,与ah无关

汇编语言的特点

  • 可以直接访问、控制各种硬件设备,比如存储器、CPU等,能最大限度地发挥硬件的功能

  • 能够不受编译器的限制,对生成的二进制代码进行完全的控制

  • 目标代码简短,占用内存少,执行速度快

  • 汇编指令是机器指令的助记符,同机器指令一一对应。每一种CPU都有自己的机器指令集汇编指令集,所以汇编语言不具备可移植性

  • 知识点过多,开发者需要对CPU等硬件结构有所了解,不易于编写、调试、维护

  • 不区分大小写,比如mov和MOV是一样的

汇编语言的特点

  • 可以直接访问、控制各种硬件设备,比如存储器、CPU等,能最大限度地发挥硬件的功能

  • 能够不受编译器的限制,对生成的二进制代码进行完全的控制

  • 目标代码简短,占用内存少,执行速度快

  • 汇编指令是机器指令的助记符,同机器指令一一对应。每一种CPU都有自己的机器指令集汇编指令集,所以汇编语言不具备可移植性

  • 知识点过多,开发者需要对CPU等硬件结构有所了解,不易于编写、调试、维护

  • 不区分大小写,比如mov和MOV是一样的

通用寄存器

AX,BX,CX,DX这4个称为通用寄存器,通常用来存放一般性的数据,由于这些寄存器是16位的,为了兼容旧代CPU,所以可拆分了8位
AX = AH AL
BX = BH BL
CX = CH CL
DX = DH DL

图片 3

寻找物理地址过程

2. 物理地址

  • 8086CPU的地址总线有20位,但寄存器只有16位(注意这里不是数据总线),所以为了能访问内存的全部地址,寻址方式为 物理地址=段地址 * 16 偏移地址
  • 也就是说,数据总线一次传两个值,一个值为段地址,一个值为偏移地址,这里16是怎么来的呢,其实就是2的20次方除以2的16次方的结果
  • 段地址的物理地址必须是16的倍数
  • 段地址的长度最大为2的16次方也就是64KB(算2的多少次方时记住2的10次方就是1024)

汇编的用途(哥么我学了能干啥?)

  • 编写驱动程序、操作系统(比如Linux内核的某些关键部分)
  • 对性能要求极高的程序或者代码片段,可与高级语言混合使用
  • 软件安全
    • 病毒分析与防治
    • 逆向加壳脱壳破解外挂免杀加密解密漏洞黑客
  • 理解整个计算机系统的最佳起点和最有效途径
  • 为编写高效代码打下基础
  • 弄清代码的本质
    • 函数的本质究竟是什么?
    • a a a 底层如何执行的?
    • 编译器到底帮我们干了什么?
    • DEBUG模式和RELEASE模式有什么关键的地方被我们忽略
    • ......

最后来句装13的话

越底层越单纯!真正的程序员都需要了解的一门非常重要的语言,汇编!

汇编的用途(哥么我学了能干啥?)

  • 编写驱动程序、操作系统(比如Linux内核的某些关键部分)
  • 对性能要求极高的程序或者代码片段,可与高级语言混合使用
  • 软件安全
    • 病毒分析与防治
    • 逆向加壳脱壳破解外挂免杀加密解密漏洞黑客
  • 理解整个计算机系统的最佳起点和最有效途径
  • 为编写高效代码打下基础
  • 弄清代码的本质
    • 函数的本质究竟是什么?
    • a a a 底层如何执行的?
    • 编译器到底帮我们干了什么?
    • DEBUG模式和RELEASE模式有什么关键的地方被我们忽略
    • ......

最后来句装13的话

越底层越单纯!真正的程序员都需要了解的一门非常重要的语言,汇编!

段的概念

图片 4

image.png

3. CS和IP

CS代码段寄存器(段寄存器还有三个:DS、SS、ES)和IP指令指针寄存器是8086中两个最关键的寄存器,也就是说,任意时刻,CPU将CS:IP指向的内容当作指令执行

8086启动时CS=FFFFH,IP=0000H,也就是说执行的第一条指令是FFFF:0000(物理地址为FFFF0H)

汇编语言的种类

  • 目前讨论比较多的汇编语言有

    • 8086汇编(8086处理器是16bit的CPU)
    • Win32汇编
    • Win64汇编
    • ARM汇编(嵌入式、Mac、iOS)
    • ......
  • 我们iPhone里面用到的是ARM汇编,但是不同的设备也有差异.因CPU的架构不同.

架构 设备
armv6 iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch
armv7 iPhone3GS, iPhone4, iPhone4S,iPad, iPad2, iPad3(The New iPad), iPad mini, iPod Touch 3G, iPod Touch4
armv7s iPhone5, iPhone5C, iPad4(iPad with Retina Display)
arm64 iPhone5S 以后 iPhoneX , iPad Air, iPad mini2以后

汇编语言的种类

  • 目前讨论比较多的汇编语言有

    • 8086汇编(8086处理器是16bit的CPU)
    • Win32汇编
    • Win64汇编
    • ARM汇编(嵌入式、Mac、iOS)
    • ......
  • 我们iPhone里面用到的是ARM汇编,但是不同的设备也有差异.因CPU的架构不同.

架构 设备
armv6 iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch
armv7 iPhone3GS, iPhone4, iPhone4S,iPad, iPad2, iPad3(The New iPad), iPad mini, iPod Touch 3G, iPod Touch4
armv7s iPhone5, iPhone5C, iPad4(iPad with Retina Display)
arm64 iPhone5S 以后 iPhoneX , iPad Air, iPad mini2以后

段寄存器

CS和IP是CPU中两个关键的寄存器,CS为代码寄存器,IP为指令指针寄存器,假设CS = M,IP为N,CPU将从Mx16 N单元开始读取一条指令并执行。执行过程:
1.cs与ip放入地址加法器,计算得到地址
2.地址总线传送该地址,然后在内存中找到该值
3.值通过数据总线传送回cpu的控制电路
4.送入到指令缓存器
5.执行控制器执行指令

4. 修改CS和IP的值

修改前面通用寄存器AX等时可以用转移指令mov,但是CS和IP只能用传送指令jmp,比如jmp AAAA:BBBB的意思就是CS=AAAA,IP=BBBB;也可以单独修改IP的值,但是必须用寄存器间接来修改,比如jmp bx的意思就是把BX的值赋给IP

几个必要的常识

  • 要想学好汇编,首先需要了解CPU等硬件结构
  • APP/程序的执行过程

图片 515193672391363.jpg

  • 硬件相关最为重要是CPU/内存
  • 在汇编中,大部分指令都是和CPU与内存相关的

几个必要的常识

  • 要想学好汇编,首先需要了解CPU等硬件结构
  • APP/程序的执行过程

图片 6

  • 硬件相关最为重要是CPU/内存
  • 在汇编中,大部分指令都是和CPU与内存相关的

修改CS、IP指令

修改普通寄存器的指令类似于 MOV ax,16move bx,123,表示把16送进ax寄存器,把123送进bx寄存器,大部分都可以通过mov指令来修改寄存器,mov指令被称为传送指令
但是,mov指令不能用于设置CS和IP,因为它们有专用的指令jmp,用法:jmp 段地址:偏移地址

第三章 寄存器(内存访问)

总线

图片 715193692496345.jpg图片 815193692648349.jpg

  • 每一个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互
  • 总线:一根根导线的集合
  • 总线的分类
    • 地址总线
    • 数据总线
    • 控制总线

图片 915193693448725.jpg

举个例子

图片 10来至书上的截图

  • 地址总线
    • 它的宽度决定了CPU的寻址能力
    • 8086的地址总线宽度是20,所以寻址能力是1M

图片 11

  • 数据总线
    • 它的宽度决定了CPU的单次数据传送量,也就是数据传送速度
    • 8086的数据总线宽度是16,所以单次最大传递2个字节的数据
  • 控制总线
    • 它的宽度决定了CPU对其他器件的控制能力、能有多少种控制

做个小练习

  • 一个CPU 的寻址能力为8KB,那么它的地址总线的宽度为____
  • 8080,8088,80286,80386 的地址总线宽度分别为16根,20根,24根,32根.那么他们的寻址能力分别为多少____KB, ____MB,____MB,____GB?
  • 8080,8088,8086,80286,80386 的数据总线宽度分别为8根,8根,16根,16根,32根.那么它们一次可以传输的数据为:____B,____B,____B,____B,____B,
  • 从内存中读取1024字节的数据,8086至少要读____次,80386至少要读取____次.

答案

图片 12练习

总线

  • 每一个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互
  • 总线:一根根导线的集合
  • 总线的分类
    • 地址总线
    • 数据总线
    • 控制总线

举个例子

图片 13

  • 地址总线
    • 它的宽度决定了CPU的寻址能力
    • 8086的地址总线宽度是20,所以寻址能力是1M

图片 14

  • 数据总线
    • 它的宽度决定了CPU的单次数据传送量,也就是数据传送速度
    • 8086的数据总线宽度是16,所以单次最大传递2个字节的数据
  • 控制总线
    • 它的宽度决定了CPU对其他器件的控制能力、能有多少种控制

图片 15练习

寄存器(内存访问)

图片 16

image.png

1. 段寄存器不能直接赋值,要通过其他寄存器来中转;也不能做加减运算

内存

图片 17各类存储区的逻辑连接图片 18各类存储器的逻辑连接-物理地址对应图图片 19各类存储器的物理地址情况

  • 内存地址空间的大小受CPU地址总线宽度的限制。8086的地址总线宽度为20,可以定位2^20个不同的内存单元(内存地址范围0x00000~0xFFFFF),所以8086的内存空间大小为1MB

  • 0x00000~0x9FFFF:主存储器。可读可写

  • 0xA0000~0xBFFFF:向显存中写入数据,这些数据会被显卡输出到显示器。可读可写

  • 0xC0000~0xFFFFF:存储各种硬件系统信息。只读

学习进制的障碍

很多人学不好进制,原因是总以十进制为依托去考虑其他进制,需要运算的时候也总是先转换成十进制,这种学习方法是错误的.我们为什么一定要转换十进制呢?仅仅是因为我们对十进制最熟悉,所以才转换.每一种进制都是完美的,想学好进制首先要忘掉十进制,也要忘掉进制间的转换!

内存

图片 20各类存储区的逻辑连接图片 21各类存储器的逻辑连接-物理地址对应图图片 22各类存储器的物理地址情况

  • 内存地址空间的大小受CPU地址总线宽度的限制。8086的地址总线宽度为20,可以定位2^20个不同的内存单元(内存地址范围0x00000~0xFFFFF),所以8086的内存空间大小为1MB

  • 0x00000~0x9FFFF:主存储器。可读可写

  • 0xA0000~0xBFFFF:向显存中写入数据,这些数据会被显卡输出到显示器。可读可写

  • 0xC0000~0xFFFFF:存储各种硬件系统信息。只读

学习进制的障碍

很多人学不好进制,原因是总以十进制为依托去考虑其他进制,需要运算的时候也总是先转换成十进制,这种学习方法是错误的.我们为什么一定要转换十进制呢?仅仅是因为我们对十进制最熟悉,所以才转换.每一种进制都是完美的,想学好进制首先要忘掉十进制,也要忘掉进制间的转换!

mov指令

1.将数据送入寄存器
2.将一个寄存器中的内存送入到另一个寄存器
3.将内存单元地址送入到寄存器 mov 寄存器名,内存单元地址mov a1, [0]
[...]表示一个内存单元,[...]中的0表示内存单元的偏移地址
段地址默认存放在DS中

图片 23

image.png

图片 24

image.png

图片 25

image.png

2. 关于数据和指令

首先数据和指令其实都是以101010的二进制形式存放在内存中,只是CPU规定了CS IP(段地址 偏移地址)指向的内存当作指令来执行,DS 偏移地址指向的内存当作数据

进制的定义

  • 八进制由8个符号组成:0 1 2 3 4 5 6 7 逢八进一
  • 十进制由10个符号组成:0 1 2 3 4 5 6 7 8 9逢十进一
  • N进制就是由N个符号组成:逢N进一

进制的定义

  • 八进制由8个符号组成:0 1 2 3 4 5 6 7 逢八进一
  • 十进制由10个符号组成:0 1 2 3 4 5 6 7 8 9逢十进一
  • N进制就是由N个符号组成:逢N进一

CPU的栈机制

在8086CPU中,有两个寄存器,SS和SP,SS存放栈顶地址,SP存放偏移地址,任意时刻,SS:SP执行栈顶元素。push指令和pop指令执行时,CPU从SS和SP中得到栈顶地址。

3. 栈

栈就是一段具有特殊访问方式的内存空间,这种特殊方式就是LIFO(后进先出)。CPU用了两个指向栈顶地址的寄存器SS SP来实现这种数据结构,但是对栈大小的把控也就是栈越界的问题需要我们自己去控制和注意

  • 入栈:push ax
    • 第一步:sp - 2
    • 第二步:把ax的内容放入[ss sp] 指向的内存
  • 出栈:pop ax
    • 第一步:把[ss sp] 指向的内存中的内容放入ax
    • 第二步:sp 2

push和pop的实质就是内存传送指令

做个练习
  • 1 1 在____情况下等于 3 ?
.............

十进制由10个符号组成: 0 1 3 2 8 A B E S 7 逢十进一

如果这样定义十进制: 1 1 = 3!就对了!

这样的目的何在?传统我们定义的十进制和自定义的十进制不一样.那么这10个符号如果我们不告诉别人这个符号表,别人是没办法拿到我们的具体数据的!用于加密!

十进制由十个符号组成,逢十进一,符号是可以自定义的!!

做个练习
  • 1 1 在____情况下等于 3 ?

十进制由10个符号组成: 0 1 3 2 8 A B E S 7 逢十进一

如果这样定义十进制: 1 1 = 3!就对了!

这样的目的何在?传统我们定义的十进制和自定义的十进制不一样.那么这10个符号如果我们不告诉别人这个符号表,别人是没办法拿到我们的具体数据的!用于加密!

十进制由十个符号组成,逢十进一,符号是可以自定义的!!

4. 小知识:对寄存器清零用sub ax,ax比mov ax,0要好,因为前者只占2字节机器码,后者占3字节机器码

进制的运算

进制的运算

5. 对段的理解:

图片 26

图片 27

做个练习
  • 八进制运算
    • 2 3 = __ , 2 * 3 = __ ,4 5 = __ ,4 * 5 = __.
    • 277 333 = __ , 276 * 54 = __ , 237 - 54 = __ , 234 / 4 = __ .
做个练习
  • 八进制运算
    • 2 3 = __ , 2 * 3 = __ ,4 5 = __ ,4 * 5 = __.
    • 277 333 = __ , 276 * 54 = __ , 237 - 54 = __ , 234 / 4 = __ .

6.一个奇怪的地方

mov ss,ax
mov xx,xx
只要执行了第一条指令(给栈段寄存器ss执行mov操作),那么下一条指令会马上紧接着执行(这是因为中断机制,这里暂不详述),而且ss sp指向的栈段的内容会发生改变,这是为什么呢?我们发现这里面有cs值、ip值、ax值(这个容易看出来),还有bp值(00 00),还有flag的值(这个我用肉眼是看不出来了。呵呵,就是那个一排英文字符)。在讲内中断这章时,你就明白了。t命令实际是引发了单步中断,执行中断例程时,CPU会将一些中断例程使用的的寄存器变量自动压栈到栈中,此例中就包括了上述的寄存器变量的值。

八进制加法表
 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 1720 21 22 23 24 25 26 27...1 1 = 2 1 2 = 3 2 2 = 4 1 3 = 4 2 3 = 5 3 3 = 61 4 = 5 2 4 = 6 3 4 = 7 4 4 = 10 1 5 = 6 2 5 = 7 3 5 = 10 4 5 = 11 5 5 = 121 6 = 7 2 6 = 10 3 6 = 11 4 6 = 12 5 6 = 13 6 6 = 141 7 = 10 2 7 = 11 3 7 = 12 4 7 = 13 5 7 = 14 6 7 = 15 7 7 = 16
八进制加法表
 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 1720 21 22 23 24 25 26 27...1 1 = 2 1 2 = 3 2 2 = 4 1 3 = 4 2 3 = 5 3 3 = 61 4 = 5 2 4 = 6 3 4 = 7 4 4 = 10 1 5 = 6 2 5 = 7 3 5 = 10 4 5 = 11 5 5 = 121 6 = 7 2 6 = 10 3 6 = 11 4 6 = 12 5 6 = 13 6 6 = 141 7 = 10 2 7 = 11 3 7 = 12 4 7 = 13 5 7 = 14 6 7 = 15 7 7 = 16

第四章 第一个程序

八进制乘法表
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27...1*1 = 1 1*2 = 2 2*2 = 4 1*3 = 3 2*3 = 6 3*3 = 11 1*4 = 4 2*4 = 10 3*4 = 14 4*4 = 201*5 = 5 2*5 = 12 3*5 = 17 4*5 = 24 5*5 = 311*6 = 6 2*6 = 14 3*6 = 22 4*6 = 30 5*6 = 36 6*6 = 441*7 = 7 2*7 = 16 3*7 = 25 4*7 = 34 5*7 = 43 6*7 = 52 7*7 = 61
八进制乘法表
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27...1*1 = 1 1*2 = 2 2*2 = 4 1*3 = 3 2*3 = 6 3*3 = 11 1*4 = 4 2*4 = 10 3*4 = 14 4*4 = 201*5 = 5 2*5 = 12 3*5 = 17 4*5 = 24 5*5 = 311*6 = 6 2*6 = 14 3*6 = 22 4*6 = 30 5*6 = 36 6*6 = 441*7 = 7 2*7 = 16 3*7 = 25 4*7 = 34 5*7 = 43 6*7 = 52 7*7 = 61

1.一段汇编代码的完整格式

assume cs:code

code segment
...

mov ax,4c00h
int 21h

code ends

end

Debug要用p命令执行int 21h来表示程序结束

实战四则运算
 277 236 276 234  333 - 54 * 54 / 4-------- -------- -------- -------- 
实战四则运算
 277 236 276 234  333 - 54 * 54 / 4-------- -------- -------- -------- 

2.汇编程序从写出到执行的过程

图片 28

二进制的简写形式

 二进制: 1 0 1 1 1 0 1 1 1 1 0 0三个二进制一组: 101 110 111 100 八进制: 5 6 7 4四个二进制一组: 1011 1011 1100 十六进制: b b c

二进制:从0 写到 11110000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111这种二进制使用起来太麻烦,改成更简单一点的符号:0 1 2 3 4 5 6 7 8 9 A B C D E F 这就是十六进制了

二进制的简写形式

 二进制: 1 0 1 1 1 0 1 1 1 1 0 0三个二进制一组: 101 110 111 100 八进制: 5 6 7 4四个二进制一组: 1011 1011 1100 十六进制: b b c

二进制:从0 写到 11110000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111这种二进制使用起来太麻烦,改成更简单一点的符号:0 1 2 3 4 5 6 7 8 9 A B C D E F 这就是十六进制了

3.连接的作用

图片 29

数据的宽度

数学上的数字,是没有大小限制的,可以无限的大。但在计算机中,由于受硬件的制约,数据都是有长度限制的,超过最多宽度的数据会被丢弃。

#import <UIKit/UIKit.h>#import "AppDelegate.h"int test(){ int cTemp = 0x1FFFFFFFF; return cTemp;}int main(int argc, char * argv[]) { printf("%xn",test; @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}

数据的宽度

数学上的数字,是没有大小限制的,可以无限的大。但在计算机中,由于受硬件的制约,数据都是有长度限制的,超过最多宽度的数据会被丢弃。

#import <UIKit/UIKit.h>#import "AppDelegate.h"int test(){ int cTemp = 0x1FFFFFFFF; return cTemp;}int main(int argc, char * argv[]) { printf("%xn",test; }}

4.Debug加载汇编exe文件后三个值得关注的寄存器

  1. cx存放着代码大小,以字节为单位
![](https://upload-images.jianshu.io/upload_images/1477016-486985b3246dfcbd.png)
  1. ds存放着程序所在的内存区的段地址
  2. cs的值在ds的基础上加10h(物理地址加了100h,也就是256字节),这段区域是存放着PSP
![](https://upload-images.jianshu.io/upload_images/1477016-30744fcc3cc2d4ce.png)

计算机中常见的数据宽度

  • 位: 1个位就是1个二进制位.0或者1
  • 字节: 1个字节由8个Bit组成.内存中的最小单元Byte.
  • 字: 1个字由2个字节组成,这2个字节分别称为高字节和低字节.
  • 双字(Doubleword): 1个双字由两个字组成

那么计算机存储数据它会分为有符号数和无符号数.那么关于这个看图就理解了!

图片 3015178439312380.jpg

无符号数,直接换算!有符号数:正数: 0 1 2 3 4 5 6 7 负数: F E D B C A 9 8 -1 -2 -3 -4 -5 -6 -7 -8

计算机中常见的数据宽度

  • 位: 1个位就是1个二进制位.0或者1
  • 字节: 1个字节由8个Bit组成.内存中的最小单元Byte.
  • 字: 1个字由2个字节组成,这2个字节分别称为高字节和低字节.
  • 双字(Doubleword): 1个双字由两个字组成

那么计算机存储数据它会分为有符号数和无符号数.那么关于这个看图就理解了!

无符号数,直接换算!有符号数:正数: 0 1 2 3 4 5 6 7 负数: F E D B C A 9 8 -1 -2 -3 -4 -5 -6 -7 -8

第五章 [BX]和loop指令

自定义进制符号

自定义进制符号

1.Loop指令

loop就是汇编中的循环,循环次数用寄存器cx来控制

图片 31

练习
  • 现在有10进制数 10个符号分别是:2,9,1,7,6,5,4, 8,3 , A 逢10进1 那么: 123 234 = ____
十进制: 0 1 2 3 4 5 6 7 8 9自定义: 2 9 1 7 6 5 4 8 3 A 92 99 91 97 96 95 94 98 93 9A 12 19 11 17 16 15 14 18 13 1A 72 79 71 77 76 75 74 78 73 7A 62 69 61 67 66 65 64 68 63 6A 52 59 51 57 56 55 54 58 53 5A 42 49 41 47 46 45 44 48 43 4A 82 89 81 87 86 85 84 88 83 8A 32 39 31 37 36 35 34 38 33 3A 922

那么刚才通过10进制运算可以转化10进制然后查表!但是如果是其他进制.我们就不能转换,要直接学会查表

  • 现在有9进制数 9个符号分别是:2,9,1,7,6,5,4, 8,3 逢9进1 那么: 123 234 = ____
十进制: 0 1 2 3 4 5 6 7 8 自定义: 2 9 1 7 6 5 4 8 3 92 99 91 97 96 95 94 98 93 12 19 11 17 16 15 14 18 13 72 79 71 77 76 75 74 78 73 62 69 61 67 66 65 64 68 63 52 59 51 57 56 55 54 58 53 42 49 41 47 46 45 44 48 43 82 89 81 87 86 85 84 88 83 32 39 31 37 36 35 34 38 33 922
练习
  • 现在有10进制数 10个符号分别是:2,9,1,7,6,5,4, 8,3 , A 逢10进1 那么: 123 234 = ____
十进制: 0 1 2 3 4 5 6 7 8 9自定义: 2 9 1 7 6 5 4 8 3 A 92 99 91 97 96 95 94 98 93 9A 12 19 11 17 16 15 14 18 13 1A 72 79 71 77 76 75 74 78 73 7A 62 69 61 67 66 65 64 68 63 6A 52 59 51 57 56 55 54 58 53 5A 42 49 41 47 46 45 44 48 43 4A 82 89 81 87 86 85 84 88 83 8A 32 39 31 37 36 35 34 38 33 3A 922

那么刚才通过10进制运算可以转化10进制然后查表!但是如果是其他进制.我们就不能转换,要直接学会查表

  • 现在有9进制数 9个符号分别是:2,9,1,7,6,5,4, 8,3 逢9进1 那么: 123 234 = ____
十进制: 0 1 2 3 4 5 6 7 8 自定义: 2 9 1 7 6 5 4 8 3 92 99 91 97 96 95 94 98 93 12 19 11 17 16 15 14 18 13 72 79 71 77 76 75 74 78 73 62 69 61 67 66 65 64 68 63 52 59 51 57 56 55 54 58 53 42 49 41 47 46 45 44 48 43 82 89 81 87 86 85 84 88 83 32 39 31 37 36 35 34 38 33 922

2.Debug中用p命令来快速执行完一个Loop,用g 偏移地址快速执行到某一行

寄存器

内部部件之间由总线连接

图片 3215193738988252.jpg

  • 对程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制
  • 不同的CPU,寄存器的个数、结构是不相同的

寄存器

内部部件之间由总线连接

图片 33

  • 对程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制
  • 不同的CPU,寄存器的个数、结构是不相同的

3.一段安全的内存空间

0:200 2ff这段256字节的空间很安全适合我们学习编码

图片 34

通用寄存器

  • ARM64拥有有31个64位的通用寄存器 x0 到 x30,这些寄存器通常用来存放一般性的数据,称为通用寄存器

    • 那么w0 到 w28 这些是32位的. 因为64位CPU可以兼容32位.所以可以只使用64位寄存器的低32位.
    • 比如 w0 就是 x0的低32位!

    图片 3515193699098685.jpg

  • 通常,CPU会先将内存中的数据存储到通用寄存器中,然后再对通用寄存器中的数据进行运算

  • 假设内存中有块红色内存空间的值是3,现在想把它的值加1,并将结果存储到蓝色内存空间

    图片 3615193703231861.jpg

  • CPU首先会将红色内存空间的值放到X0寄存器中:mov X0,红色内存空间
  • 然后让X0寄存器与1相加:add X0,1
  • 最后将值赋值给内存空间:mov 蓝色内存空间,X0

通用寄存器

  • ARM64拥有有31个64位的通用寄存器 x0 到 x30,这些寄存器通常用来存放一般性的数据,称为通用寄存器

    • 那么w0 到 w28 这些是32位的. 因为64位CPU可以兼容32位.所以可以只使用64位寄存器的低32位.
    • 比如 w0 就是 x0的低32位!

    图片 37

Xcode上的模拟器是X86的

图片 38

  • 通常,CPU会先将内存中的数据存储到通用寄存器中,然后再对通用寄存器中的数据进行运算
  • 假设内存中有块红色内存空间的值是3,现在想把它的值加1,并将结果存储到蓝色内存空间

图片 39

  • CPU首先会将红色内存空间的值放到X0寄存器中:mov X0,红色内存空间
  • 然后让X0寄存器与1相加:add X0,1
  • 最后将值赋值给内存空间:mov 蓝色内存空间,X0

第七章 更灵活的定位内存地址的方法

pc寄存器(program counter)

  • 为指令指针寄存器,它指示了CPU当前要读取指令的地址
  • 在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息
  • CPU在工作的时候把有的信息看做指令,有的信息看做数据,为同样的信息赋予了不同的意义
    • 比如 1110 0000 0000 0011 0000 1000 1010 1010
    • 可以当做数据 0xE003008AA
    • 也可以当做指令 mov x0, x8
  • CPU根据什么将内存中的信息看做指令?
    • CPU将pc指向的内存单元的内容看做指令
    • 如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元必然被pc指向过

pc寄存器(program counter)

  • 为指令指针寄存器,它指示了CPU当前要读取指令的地址
  • 在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息
  • CPU在工作的时候把有的信息看做指令,有的信息看做数据,为同样的信息赋予了不同的意义
    • 比如 1110 0000 0000 0011 0000 1000 1010 1010
    • 可以当做数据 0xE003008AA
    • 也可以当做指令 mov x0, x8
  • CPU根据什么将内存中的信息看做指令?
    • CPU将pc指向的内存单元的内容看做指令
    • 如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元必然被pc指向过

1.and和or指令

  • and可将操作对象相应位设为0
  • or可将操作对象相应位设为1

比如:
将al的第6位设为0的指令为: and al,10111111b
将al的第6位设为1的指令为: or al,01000000b

bl指令

  • CPU从何处执行指令是由pc中的内容决定的,我们可以通过改变pc的内容来控制CPU执行目标指令

  • ARM64提供了一个mov指令,可以用来修改大部分寄存器的值,比如

    • mov x0,#10、mov x1,#20
  • 但是,mov指令不能用于设置pc的值,ARM64没有提供这样的功能

  • ARM64提供了另外的指令来修改PC的值,这些指令统称为转移指令,最简单的是bl指令

bl指令

  • CPU从何处执行指令是由pc中的内容决定的,我们可以通过改变pc的内容来控制CPU执行目标指令

  • ARM64提供了一个mov指令,可以用来修改大部分寄存器的值,比如

    • mov x0,#10、mov x1,#20
  • 但是,mov指令不能用于设置pc的值,ARM64没有提供这样的功能

  • ARM64提供了另外的指令来修改PC的值,这些指令统称为转移指令,最简单的是bl指令

2.字母大小写转换的另一种方式

除了根据ASCII值得知“小写字母=大写字母 20H”这个规律以外,从小写字母和大写字母ASCII码的二进制形式来看,除了第5位不一样其余位数全部相同,小写字母第5位为1,大写字母第5为0,所以可以运用and和or指令来快捷转换大小写

bl指令 -- 练习

现在有两段代码!假设程序先执行A,请写出指令执行顺序.最终寄存器x0的值是多少?

_A: mov x0,#0xa0 mov x1,#0x00 add x1, x0, #0x14 mov x0,x1 bl _B mov x0,#0x0 ret_B: add x0, x0, #0x10 ret

bl指令 -- 练习

现在有两段代码!假设程序先执行A,请写出指令执行顺序.最终寄存器x0的值是多少?

_A: mov x0,#0xa0 mov x1,#0x00 add x1, x0, #0x14 mov x0,x1 bl _B mov x0,#0x0 ret_B: add x0, x0, #0x10 ret

汇编查看方式:打开Debug->Workflow->Always Show

图片 40

图片 41

用一下命令进行DDLB调试:

ni : 单步走s : 跳入register write/read pc 0x100

利用Command shift F查看二进制

图片 42

注意: bl命令可操作PC寄存器mov是传送指令 不可操作PC寄存器#10 #代表后面跟的是一个常数

3.寻址方式

  • [bx/si/di idata]
  • [bx si/di]
  • [bx si/di idata]

4.栈的应用

图片 43

5.二重循环

里层循环开始前入栈cx,里层循环结束出栈cx

图片 44

本文由星彩网app下载发布于计算机编程,转载请注明出处:持续更新,初识汇编_ARM64_001

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。