汇编语言实验

HarderHeng Lv5

一、Debug的使用

  • -r查看寄存器

  • -r ax 改变ax寄存器的值

  • -d 加内存地址 查看内存

  • -d 连续查看内存地址

  • -e 加内存地址 修改内存中的内容

  • -a 加地址 使指令指针寄存器指向指定的地址,并且在接下来的指令中可以将指令写入地址中

  • -t 单步执行

  • -u 加地址将内存地址中的机器码变成汇编语言

二、

CS + IP构成了指令的地址

通用寄存器可以分为高八位和低八位,如果计算结果越界,高位会被直接省略掉,如果是在高八位或者低八位中单独越界,低八位的进位也不会进到高八位中

MUL乘法指令

使用mul乘法指令时,可以使用两个8位的数相乘,也可以使用两个16位。

如果是8位,第一个乘数默认放在al中,如果是16位第一个乘数默认放在ax中。

如果结果超过8位结果默认放在ax中,如果结果超过16位,高位结果放在dx中,低位结果放在ax中。

mul指令一般不将立即数作为操作数(ARM和8086都是)

DIV除法指令

除数可以是8位也可以是16位,被除数是16位或者32位,根据被除数来确定。

被除数如果是16位就存放在AX中,如果是32位就存放在DX和AX中。

也就是说被除数到底是多少根据除数来决定

AND与运算指令

and 后面可以有两个操作数,结果就是两个数相与的结果

OR指令

和and类似

三、汇编语言中segment

现在的x86-64体系已经废除了内存分段机制

DATA数据段

也就相当于c语言中所有的变量存储的段,不管是有没有初始值都可以存储在这里。

声明变量时需要指定变量的长度。

1
2
3
DATA SEGMENT
···
DATA ENDS

CODE代码段

代码段中定义了真正要执行的代码,通常会有一个进入函数标签START或者**_START,在Windows系统中是main或者_main,这里是程序的入口,在整个汇编代码的最后,要写上end start**来表示start是程序入口。

为了让汇编器知道我们代码中的程序段就是cs段寄存器,数据段就是ds段寄存器,需要使用一个伪指令assume cd:code, ds:data

1
2
3
4
5
6
7
8
9
CODE SEGMENT
START:
MOV AX, DATA ;将
MOV DS, AX
···

CODE ENDS

END START ;表示程序入口

二、80x86

8086汇编代表了x86汇编语言,编写汇编语言时往往使用大写

8086是16位,基于8086系列有80386的32位,寄存器都是16位。
通用寄存器

  • AX 累加寄存器
  • BX 基址寄存器
  • CX 计数寄存器
  • DX 数据寄存器

地址指针寄存器

  • SP 堆栈寄存器
  • BP 基址指针寄存器

变址寄存器

  • SI 源变址寄存器
  • DI 目标变址寄存器

段寄存器

  • CS 代码段
  • DS 数据段
  • ES 附加段
  • SS 堆栈段

段寄存器的意义

段地址x16 + 偏移地址 = 物理地址

段地址就是段寄存器中的值,偏移地址就是地址指针寄存器变址寄存器

CS+IP = 执行代码的位置

SS+SP=堆栈中的位置

指令

  • shl ax, 6左移几位
  • shr ax, 6右移几位
  • rol ax, 2循环左移
  • ror ax, 2循环右移
  • inc ax ax++
  • dec ax ax–
  • nop 空指令
  • xchg ax,bx 交换两个寄存器
  • neg ax 取负数
  • word ptr[] 强制转换字节和字,word可以换成byte

三、ARM汇编

伪指令

伪指令并不是真正的arm指令。

  • .text 意味着接下来的段是代码段,作用和area code类似

  • .global 全局定义一个标签

  • .type 指定一个标签的类型,常用于指定一个标签是函数

  • RSB R1, R0, #0 将ro的值与0相减,并将值变成r1,也就是将值变成负数

  • Title: 汇编语言实验
  • Author: HarderHeng
  • Created at : 2024-04-18 18:53:07
  • Updated at : 2024-11-05 17:32:58
  • Link: https://harderheng.life/2024/04/18/汇编语言实验/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments