ARM02汇编指令

文章目录

      • 一、keil软件介绍
        • 1.1 创建工程
        • 1.2 解析start.s文件(重点)
        • 1.3 乱码解决
        • 1.4 更换背景颜色
        • 1.5 C语言内存分布
        • 1.6 解析map.lds文件(重点)
        • 1.7 常见错误信息
        • 1.8 仿真
      • 二、汇编三种符号
        • 2.1 汇编指令
        • 2.2 伪指令
        • 2.3 伪操作
      • 三、汇编指令格式
        • 3.1 格式
          • 3.2 注意事项
      • 四、数据操作指令
        • 4.1 数据搬移指令 mov mvn
        • 4.2 立即数
        • 4.3 伪指令 ldr
        • 4.4 移位操作指令
        • 4.5 位运算操作指令
          • 4.5.1 代码1
          • 4.5.2 代码2
        • 4.6 算数运算指令
        • 4.7 比较指令
      • 五、跳转指令
        • 5.1 指令码
      • 作业1
      • 作业2
      • 总结

一、keil软件介绍

1.1 创建工程

跟着文档进行创建就可以,注意不要出现中文路径

1.2 解析start.s文件(重点)

.text @文本段
.global _start @ 声明一个_start函数入口
_start:  @ _start标签,相当于C语言中函数

    mov r0,#0x1  @ 一条汇编指令
    
stop:  @ stop标签,相当于C语言中函数
    b stop @ 跳转到stop标签下的第一条指令执行,相当于C语言中while(1)
    
.end @结束标志

1.3 乱码解决

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ax8jQPO4-1692022974257)(evernotecid://3E0E4EC3-DFE7-4A43-A61C-6137F75331C6/appyinxiangcom/14761362/ENNote/p999?hash=5c85f58c1fe3896ffa652dc31c6d2f44)]

1.4 更换背景颜色

将群里下发global.prop文件替换到C:\Keil_v5\UV4,重启keil软件

1.5 C语言内存分布

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ichTV9H9-1692022950793)(evernotecid://3E0E4EC3-DFE7-4A43-A61C-6137F75331C6/appyinxiangcom/14761362/ENNote/p999?hash=fca5618d46730e99c5649c42f3babd0d)]

1.6 解析map.lds文件(重点)

map.lds文件:链接脚本文件
作用:给编译器进行使用,告诉编译器对各个段,如何进行分布

/*输出格式:32位可执行程序,小端对齐*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
/*输出架构:arm架构*/
OUTPUT_ARCH(arm)
/*入口:_start*/
ENTRY(_start)
/*段*/
SECTIONS
{
    . = 0x00000000;/*入口地址*/
    . = ALIGN(4);/*4字节对齐*/
    .text      :
    {
        ./Objects/start.o(.text) /*第一个文件存放start.o文件,指定start.o位置*/
        *(.text) /*其余文件没有要求,编译器随便放*/
    }
    . = ALIGN(4);
    .rodata : /*只读数据段*/
    { *(.rodata) }
    . = ALIGN(4);
    .data :  /*数据段*/
    { *(.data) }
    . = ALIGN(4);
    __bss_start = .; 
    .bss : /*.bss段*/
     { *(.bss) }
    __bss_end__ = .;
}

1.7 常见错误信息

c:/program files (x86)/codesourcery/ld.exe: cannot find ./start.o =====> 不能找到./start.o
解决方法:
    1)在当前工程下,查看start.o位置 ======> 编译器决定start.o在哪个位置
    2)修改map.lds文件

1.8 仿真

在这里插入图片描述

二、汇编三种符号

2.1 汇编指令

编译器将一条汇编指令编译生成机器码,占用代码段空间

2.2 伪指令

伪指令本身不是一条指令,编译器可以将其编译生成多条指令,共同完成一条指令功能

2.3 伪操作

指导编译器对代码如何进行编译,所有以.开头的为伪操作,伪操作不占用代码段空间

三、汇编指令格式

3.1 格式

{cond}{s} Rd,Rn,#oprand2
:指令码
{cond}:条件码
加条件码:指令有条件执行
不加条件码:指令默认无条件执行
{s}:状态位
加s:影响CPSR寄存器
不加s:不影响CPSR寄存器
Rd:目标寄存器
Rn:第一操作寄存器
#oprand2:第二操作数
1)立即数
2)寄存器
3)有效数:将一个数按位取反之后,如果这个数为立即数,说明这个数为有效数

3.2 注意事项

1、{cond}{s}需要连在一起编写
2、Rd,Rn,#oprand2需要用逗号分隔开
3、{cond}{s}和Rd,Rn,#oprand2需要用空格隔开
4、一条汇编指令占用一行,并且没有分号
5、汇编中不区分大小写

四、数据操作指令

4.1 数据搬移指令 mov mvn

指令码:mov mvn
指令格式:{cond}{s} Rd,#oprand2
mov ====> 将第二操作数进行赋值
mvn ====> 将第二操作数,按位进行取反之后,进行赋值

mov r0,#0xf  @ r0 = 0xf ====> 立即数
mov r1,#0xff  @ r1 = 0xff  ====> 立即数
mov r8,r1 @ r8 = r1 = 0xff  ====> 寄存器
@ mov r2,#0xfff  @ r2 = 0xfff ====> error
@ mov r3,#0xffff  @ r3 = 0xfffff  ====> error
@ mov r4,#0xfffff  @ r4 = 0xfffff  ====> error
mov r5,#0xffffff  @ r5 = 0xffffff = ~r5 = 0xff000000   ====> 有效数
mov r6,#0xfffffff  @ r6 = 0xfffffff = ~r6 = 0xf0000000 ====> 有效数
mov r7,#0xffffffff @ r7 = 0xffffffff = ~r7 = 0 ====> 有效数
mov r0,#0xff   @ r0 = 0xff
mvn r1,#0xff   @ r1 = ~ r1 = 0xffffff00 

4.2 立即数

在这里插入图片描述

1、从判断的数中,找到0~0xff之间的数 ===> 判断的这个数所有1包含
2、将找到的0~0xff之间的数,循环右移偶数位 ===> 低位移出,补到高位
3、如果能够得到你要判断的那个数,说明这个数就是立即数
判断的数0 ~ 0xff之间数循环右移偶数是否立即数

判断的数0 ~ 0xff之间数循环右移偶数是否立即数
0xf0xf0
0xf000000f0xff4
0xff0000000xff8
0x000000ff0xff0
0x1fe000000xff11不是
0x1f8000000x7E10
0x0000000f =====> 判断的数
0000 0000 0000 0000 0000 0000 0000 1111  =====> 判断的数
0 ~ 0xff之间数:0xf
循环右移偶数: 0    

0xf000000f =====> 判断的数
1111 0000 0000 0000 0000 0000 0000 1111  =====> 判断的数
0000 0000 0000 0000 0000 0000 1111 1111  =====> 0 ~ 0xff之间数
0 ~ 0xff之间数: 0xff
循环右移偶数: 4


0xff000000 =====> 判断的数
1111 1111 0000 0000 0000 0000 0000 0000  =====> 判断的数
0000 0000 0000 0000 0000 0000 1111 1111  =====> 0 ~ 0xff之间数
0 ~ 0xff之间数:0xff
循环右移偶数: 8

0x000000ff =====> 判断的数
0000 0000 0000 0000 0000 0000 1111 1111  =====> 判断的数
0000 0000 0000 0000 0000 0000 1111 1111  =====> 0 ~ 0xff之间数
0 ~ 0xff之间数:0xff
循环右移偶数: 0

0x1fe00000=====> 判断的数
0001 1111 1110 0000 0000 0000 0000 0000  =====> 判断的数
0000 0000 0000 0000 0000 0000 1111 1111  =====> 0 ~ 0xff之间数
0 ~ 0xff之间数:0xff
循环右移偶数: 11

0x1f800000 =====> 判断的数
0001 1111 1000 0000 0000 0000 0000 0000  =====> 判断的数
0000 0000 0000 0000 0000 0000 0111 1110  =====> 0x7E
0 ~ 0xff之间数:0x7E
循环右移偶数: 10

4.3 伪指令 ldr

思考:在0~4G空间,有很多数都不是立即数,那么如何进行赋值呢?
指令码:ldr
格式:ldr 寄存器,=值

ldr r0,=0xfff  @ r0 = 0xfff
ldr r1,=0xffff @ r1 = 0xffff
ldr r2,=0xfffff @ r2 = 0xfffff

4.4 移位操作指令

指令码:lsl lsr ror asr
指令格式:{cond}{s} Rd,Rn,#oprand2
lsl:逻辑左移 =====> 特点:无符号数左移,高位移出,低位补0
lsr:逻辑右移 =====> 特点:无符号数右移,低位移出,高位补0
ror:循环右移 =====> 特点:低位移出,补到高位
asr:算数右移 =====> 特点:低位移出,高位补符号位

mov r0,#0xff  @ r0 = 0xff = 0000 0000 0000 0000 0000 0000 1111 1111
    
    @1.将r0寄存器中的值,逻辑左移4位,并且存放到目标寄存器r1
    @ 0000 0000 0000 0000 0000 0000 1111 1111
    @ 0000 0000 0000 0000 0000 1111 1111 0000
    lsl r1,r0,#0x4  @ r1 = r0 << 4 = 0xff0
    
    @2.将r1寄存器中的值,逻辑右移4位,并且存放到目标寄存器r2
    @ 0000 0000 0000 0000 0000 1111 1111 0000
    @ 0000 0000 0000 0000 0000 0000 1111 1111
    lsr  r2,r1,#0x4  @ r2 = r1 >> 4 = 0x000000ff
    
    @3.将r2寄存器中的值,循环右移4位,并且存放到目标寄存器r3
    @ 0000 0000 0000 0000 0000 0000 1111 1111
    @ 1111 0000 0000 0000 0000 0000 0000 1111 
    ror r3,r2,#0x4  @ r3 = 0xf000000f
    
    ldr r4,=0x8000000f
    @4.将r4寄存器中的值,算数右移4位,并且存放到目标寄存器r5
    @ 1000 0000 0000 0000 0000 0000 0000 1111 
    @ 1111 1000 0000 0000 0000 0000 0000 0000
    asr r5,r4,#0x4  @ r5 = 0xf8000000

4.5 位运算操作指令

指令码:and orr eor bic
格式:{cond}{s} Rd,Rn,#oprand2
and:按位与 =====> 与0清0,与1不变
orr:按位或 =====> 或0不变,或1置1
eor:按位异或 =====> 异或0不变,异或1取反(相同为0,相异为1)
bic:按位清零 =====> 第二操作哪一位写1,对应位进行清0

真值表
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
0 ^ 0 = 0
4.5.1 代码1
/*    
    mov r0,#0xff @ r0 = 0xff
    @ 31                               4 3210
    @ **** **** **** **** **** **** **** ****
    @ 0000 0000 0000 0000 0000 0000 1111 1111
    @ 1111 1111 1111 1111 1111 1111 1110 1111
    @将r0寄存器中第4位进行清0,保证其他位不变,并且存放到目标寄存器r0中
    @ 第一种方法:
    and r0,r0,#0xffffffef
    @ 第二种方法:推荐使用
    and r0,r0,#(~(0x1 << 4))
    @ 备注:当目标寄存器和第一操作寄存器相同,可以合并 and r0,#(~(0x1 << 4))
    @ 第三种方法
    bic r0,r0,#(0x1 << 4)
*/    
    mov r0,#0xEf @ r0 = 0xEf
    @ 0000 0000 0000 0000 0000 0000 1110 1111
    @                             1 1110 1111
    
    @将r0寄存器中第8位进行置1,保证其他位不变,并且存放到目标寄存器r1中
    orr r1,r0,#(0x1 << 8) @ r1 = 0x1ef
    
    mov r2,#0xf @ r0 = 0xf
    @ 0000 0000 0000 0000 0000 0000 0000 1111
    @                                    0111
    @将r2寄存器中第3位进行取反,保证其他位不变,并且存放到目标寄存器r3中
    eor r3,r2,#(0x1 << 3) @ r3 = 0x7
4.5.2 代码2
ldr r0,=0x12345678
@ 1> 将R0寄存器中的第[4]位清0,保持其他位不变
and r0,r0,#(~(0x1 << 4))
@ 2> 将R0寄存器中的第[7]位置1,保持其他位不变
orr r0,r0,#(0x1 << 7)
@ 3> 将R0寄存器中的第[31:28]位清0,保持其他位不变
and r0,r0,#(~(0xf << 28))
@ 4> 将R0寄存器中的第[7:4]位置1,保持其他位不变
orr r0,r0,#(0xf << 4)
@ 5> 将R0寄存器中的第[15:11]位修改位10101,保持其他位不变    
    @ 先清零
    bic r0,r0,#(0x1f << 11)
    @ 在置1
    orr r0,r0,#(0x15 << 11)

4.6 算数运算指令

指令码:add adc sub sbc mul
指令格式:{cond}{s} Rd,Rn,#oprand2
add:普通加法指令
adc:带进位加法指令 ====> CPSR寄存器中C位标志位
sub:普通减法指令
sbc:带借位减法指令
mul:乘法指令 ====> 没有第二操作数,{cond}{s} Rd,Rn

    /*
    练习题1:实现两个64位数相加
    第一个64位数:高32位r0 = 0x4 低32位r1 = 0xffffffff
    第二个64位数:高32位r2 = 0x1 低32位r3 = 0x1
    两个64位数进行相加目标高32位r4表示=0x6,低32位r5表示=00000000
    mov r0,#0x4
    mov r1,#0xffffffff
    mov r2,#0x1
    mov r3,#0x1
    adds r5,r1,r3 @ r5 = r1 + r3
    adc r4,r0,r2 @ r4 = r0 + r2 + c = 0x4 + 0x1 + 1 = 0x6
    */
    
    /*
    练习题2:实现两个64位数相减
    第一个64位数:高32位r0 = 0x4 低32位r1 = 0x4
    第二个64位数:高32位r2 = 0x1 低32位r3 = 0x5
    两个64位数进行相减目标高32位r4表示=0x2,低32位r5表示=0xffffffff
    */
    mov r0,#0x4
    mov r1,#0x4
    mov r2,#0x1
    mov r3,#0x5
    subs r5,r1,r3 @ r5 = r1 - r3
    sbc  r4,r0,r2 @ r4 = r0 - r2 - !c = 0x4 - 0x1 - 1 = 0x2
 /*乘法指令  ====> 没有第二操作数,<opcode>{cond}{s} Rd,Rn*/
     mov r0,#0x4
    mov r1,#0x5
    mul r0,r1 @ r0 = r0 * r1 = 0x14

4.7 比较指令

指令码:cmp
指令格式:{cond} Rn,#oprand2
注意点:
1)比较指令没有目标寄存器
2)比较指令本质做减法运算
3)比较指令的执行结果,会影响CPSR寄存器的NZCV位,并且不需要加s
4)比较指令和条件码搭配使用
5)前面我们所有学习的指令,都是默认无条件执行,比较指令有条件指令

mov r0,#0x4
mov r1,#0x5
cmp r0,r1     @比较r0和r1寄存器中的值
subhi r0,r0,r1 @如果r0 > r1 r0 = r0 - r1
subcc r1,r1,r0 @如果r0 < r1 r1 = r1 - r0

在这里插入图片描述

五、跳转指令

5.1 指令码

指令码:b / bl
指令格式:b / bl{cond} 标签 ====> 跳转到标签下,第一条指令执行
b:有去无回,不会保存函数返回地址到LR寄存器中
b:有去有回,会保存函数返回地址到LR寄存器中

mov r0,#0x1
mov r1,#0x2
@ b add_func @有去无回,不会保存函数返回地址到LR寄存器中
bl add_func @有去有回,会保存函数返回地址到LR寄存器中
mov r3,#0x4
b stop

add_func:
add r0,r0,r1 @ r0 = r0 + r1 = 0x1 + 0x2 = 0x3
mov pc,lr  @ 恢复现场 pc = lr

作业1

在这里插入图片描述

作业2

用for循环实现1~100之间和5050

for(i=1;i<=100;i++)
{
    sum = sum + i;
}

总结

特殊功能寄存器:sp lr pc cpsr spsr
基本格式:<opcode>{cond}{s} Rd,Rn,#oprand2
数据操作指令
    1> 数据搬移指令 mov mvn ldr
    2> 移位操作指令 lsl lsr asr ror
    3> 算数运算指令 add adc sub sbc
    4> 位运算操作指令 and orr eor bic
    5> 比较指令 cmp
跳转指令 b / bl

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78367.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot复习:(34)@EnableWebMvc注解为什么让@WebMvcAutoconfiguration失效?

它导入了DelegatingWebMvcConfiguration 它会把容器中的类型为WebMvcConfigurer的bean注入到类型为WebMvcConfigurerComposite的成员变量configurers中。 可以看到它继承了WebMvcConfigurerSupport类 而WebMvcConfigureAutoConfiguration类定义如下 可以看到一个Conditional…

Tesseract用OpenCV进行文本检测

我没有混日子&#xff0c;只是辛苦的时候没人看到罢了 一、什么是Tesseract Tesseract是一个开源的OCR&#xff08;Optical Character Recognition&#xff09;引擎&#xff0c;OCR是一种技术&#xff0c;它可以识别和解析图像中的文本内容&#xff0c;使计算机能够理解并处理…

求解方程sympy.solve

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 求解方程 sympy.solve [太阳]选择题 下列代码最后一次输出的结果是&#xff1f; import sympy x sympy.symbols(x) y x**2 2*x - 3 print("【执行】sympy.solve(y, x)") print(s…

网络通信基础

1.网络结构模式&#xff08;C/S和B/S&#xff09; (1)C/S结构模式 服务器 - 客户机&#xff0c;即 Client - Server&#xff08;C/S&#xff09;结构。 优点&#xff1a; 能充分发挥客户端 PC 的处理能力&#xff0c;很多工作可以在客户端处理后再提交给服务器&#xff…

GitKraken保姆级图文使用指南

前言 写这篇文章的原因是组内的产品和美术同学&#xff0c;开始参与到git工作流中&#xff0c;但是网上又没有找到一个比较详细的使用教程&#xff0c;所以干脆就自己写了一个[doge]。文章的内容比较基础&#xff0c;介绍了Git内的一些基础概念和基本操作&#xff0c;适合零基…

CSS变形与动画(三):animation帧动画详解(用法 + 四个例子)

文章目录 animation 帧动画使用定义例子1 字母例子2 水滴例子3 会动的边框例子4 旋转木马 animation 帧动画 定义好后作用于需要变化的标签上。 使用 animation-name 设置动画名称 animation-duration: 设置动画的持续时间 animation-timing-function 设置动画渐变速度 anim…

做好需求分析的4大关键认知

探索如何正确的需求分析&#xff1f;本文详细介绍了4大关键点&#xff0c;帮助您明确用户与产品需求、深入挖掘用户动机&#xff0c;并为产品经理提供筛选需求的实用建议。 一、什么是需求分析以及重要性 需求分析指的是在建立一个新的或改变一个现存的产品时&#xff0c;确定新…

docker run 命令30个常用参数详解

文章目录 0.前言docker run 命令示例 2.Docker run 多种用法知其然知其所以然1. 基本用法2. 启动交互式容器3. 映射端口4. 挂载文件/目录5. 设置环境变量6. 指定容器名称7. 后台运行容器8. 重启策略9. 其他参数 2. docker run 命令参数详解1. -d&#xff1a;以后台模式&#xf…

【云原生,k8s】基于Helm管理Kubernetes应用

第四阶段 时 间&#xff1a;2023年8月18日 参加人&#xff1a;全班人员 内 容&#xff1a; 基于Helm管理Kubernetes应用 目录 一、Kubernetes部署方式 &#xff08;一&#xff09;minikube &#xff08;二&#xff09;二进制包 &#xff08;三&#xff09;Kubeadm …

(白帽黑客)自学笔记

一、前言&#xff1a; 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多 google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可以先放放,以…

Unity自定义脚本的 初始模版

参考博主&#xff1a;Unity修改创建的脚本模板&#xff0c;Unity脚本模板路径_unity hub 怎么改脚本模板_先生沉默先的博客-CSDN博客 【100个 Unity实用技能】 ☀️ | Unity自定义脚本的初始模版_unity 模板脚本_呆呆敲代码的小Y的博客-CSDN博客 一&#xff0c;将脚本放到Ed…

【java毕业设计】基于Spring Boot+Vue+mysql的论坛管理系统设计与实现(程序源码)-论坛管理系统

基于Spring BootVuemysql的论坛管理系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring BootVuemysql的论坛管理系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取…

利用Python隧道爬虫ip轻松构建全局爬虫网络

嘿&#xff0c;爬虫程序员们&#xff01;你们有没有碰到过需要大规模数据爬取的情况&#xff1f;也许你们之前遇到过网站的反爬措施&#xff0c;卡住你们的进度。别担心&#xff0c;今天我来分享一个利用Python隧道爬虫ip实现的方法&#xff0c;帮助你们轻松搭建全局爬虫ip网络…

2.SpringMvc中Model、ModelMap和ModelAndView使用详解

1.前言 最近SSM框架开发web项目&#xff0c;用得比较火热。spring-MVC肯定用过&#xff0c;在请求处理方法可出现和返回的参数类型中&#xff0c;最重要就是Model和ModelAndView了&#xff0c;对于MVC框架&#xff0c;控制器Controller执行业务逻辑&#xff0c;用于产生模型数据…

OJ练习第150题——分割回文串

分割回文串 力扣链接&#xff1a;131. 分割回文串 题目 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 Java代码 class Solution {List<List…

C++ STL list

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;C之 STL list介绍和模拟实现 ☂️<3>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<4>前言&#xff1a;上次我们详细的介绍了vector&#xff0c;今天我们继续来介绍…

卷积操作后特征图尺寸,感受野,参数量的计算

文章目录 1、输出特征图的尺寸大小2、感受野的计算3、卷积核的参数量 1、输出特征图的尺寸大小 如果包含空洞卷积&#xff0c;即扩张率dilation rate不为1时&#xff1a; 2、感受野的计算 例如&#xff0c;图像经过两个3*3&#xff0c;步长为2的卷积后感受野为&#xff1a; co…

Docker数据卷容器

1.数据卷容器介绍 即使数据卷容器c3挂掉也不会影响c1和c2通信。 2.配置数据卷容器 创建启动c3数据卷容器&#xff0c;使用-v参数设置数据卷。volume为目录&#xff0c;这种方式数据卷目录就不用写了&#xff0c;直接写宿主机目录。 创建c1、c2容器&#xff0c;使用–volum…

nginx反向代理流程

一、nginx反向代理流程 反向代理&#xff1a;使用代理服务器来接受internet上的连接请求&#xff0c;然后将请求转发给内部网络中的上游服务器&#xff0c;并将上游服务器得到的结果返回给请求连接的客户端&#xff0c;代理服务器对外表现就是一个web服务器。Nginx就经常拿来做…

ByteBuffer 使用

ByteBuffer 使用 1 java.nio包中的类定义的缓冲区类型2 缓冲区常用属性2.1缓冲区的容量(capacity)2.2 缓冲区的位置(position)2.3 缓冲区的限制(limit)2.4 缓冲区的标记(mark)2.5 剩余容量 remaining/hasRemaining 3 缓冲区常用方法3.1 创建缓冲区3.1.1 allocate方法3.1.2 wrap…