汇编语言语法

CPU中的"内存"--寄存器

常用寄存器

  • AX: accumulator, 累加寄存器
  • CX: counter, 计数寄存器
  • DX: data, 数据寄存器
  • BX: base, 基址寄存器
  • SP: stack pointer, 栈指针寄存器
  • BP: base pointer, 基址指针寄存器
  • SI: source index, 源地址寄存器
  • DI: destination index, 目的变址寄存器

以上的寄存器都是16位(2个字节)的寄存器

在[A-D]X寄存器中, 每一个寄存器都是由两个8位寄存器组成的

AX: AH + AL

BX: BH + BL

CX: CH + CL

DX: DH + DL

其中H表示High, L表示Low, 左高右低是内存中地址的分布形式, 而X是eXtend中的X, 表示扩展, 因为16位寄存器确实是8位寄存器的扩展,
但是剩下的四个寄存去就没有High和Low之分了, 如果我们想要获取SP该16位寄存器中低8位的值, 需要将SP中的值MOV到AX之类的寄存器中, 在通过访问AL寄存器获取,
也许你会注意到, 为什么不直接放到AL中呢? 这是因为MOV指令的作用, 因为MOV指令操作的目标源和数据源需要时大小相同的容器(在C语言中就是变量, 其实CPU中的寄存器可以为C语言中的变量, 也就是容器)

扩展寄存器

  • EAX
  • ECX
  • EDX
  • EBX
  • ...
    通过名字我们可以判断出来, 他们与我们上面提到的常用寄存器中的AX等, 就是多了E, 其实这里的E就是从Extend中提取出来的, 表示对16位寄存器的再扩展, 成为了32位, 同上面AX与AL的关系
    一样, AX是含在EAX中的

段寄存器

这里不展开讲了, 一般段寄存器的名称是以S结尾的, 表示Sgement(段)

汇编语言

nasm命令行工具的使用

  • nasm -o
  • ndisasm: 反汇编工具

汇编语言的指令

  • NASM中所有的标签和变量都是地址, 而使用了[]表示其该地址中的值
  • DB: data byte --> 向当前的地址中的一个字节slot中传入值 usage: DB 8 注意: DB "Hello world!" 也是对的, DB命令会自动将每一个字符添加到指定的位置
  • DW: data word --> 向当前地址中的两个字节slot传入值, 就是比DB多了字节数而已, 其他性质一样 usage: DW 88888
  • DD: double word --> 向当前地址中的四个字节slot传入值, 就是比DW多了字节数而已, 其他性质一样 usage: DD 88888 789798
  • RESB: reserve byte --> 指定空余多少个连续的字节, 填充的值为0 usage: RESB 100 意思是在当前位置开始空出100个字节, 并将每一个字节的值填充为0, 执行完该指令之后, 我们程序的指令也在100字节之后了, 但是在NSAM中使用不来, 替代他的是times # db 0
  • ORG: original --> 指定了程序开始的地址, 该指令后面跟的值是在特定范围的值, 否则会对系统造成破坏 usage: ORG 0x7c00
  • JMP: jump --> 类似于C语言中的goto usage: JMP entry: 其中entry:是一个标签, 实质上就是一个地址, 使用JMP让CPU其对应的地址找指令运行
  • MOV: move --> 类似于C语言中的赋值语句 usage: MOV SS, AX 等同于SS = AX, 注意如果两边是寄存器的话, 需要保证寄存器是同位数的
  • ADD: add --> 类似C语言中的加法赋值 usage: ADD SS, AX 等同于SS = SS + AX
  • **"\("变量**: 在不同的情况下有不同的意思, 一般表示当前程序所在的内存地址, 而\)$表示的一个section的地址
  • []中括号: 中括号锁定地址, MOV BYTE [123] SI 意思是找到地址为123的那个字节的slot, 将SI里面的值赋给那个字节, 同样MOV [BX] AX是找到BX寄存器中存放的值, 并根据该值找到地址编号为该值的slot, 将AX中的值赋给他, 注意: []中可以是数字, 可以是该有B或者I的寄存器(SI, BX, BH, BL, SP, DI等), 但是不可以是其他的了(AX, CX, DX, SS)
  • ORG 0x7c00: 一般出现在GRUB等bootloader中的第一行, 该指令告诉CPU将该程序加载到内存的0x7c00地址上, 并且ORG后面的值只能是一些固定的时, 在0x7c00地址之前的内存存放的是BIOS, 所以不能将bootloader加载到0x7c00之前
  • EQU: 用来为标识符定义一个整型常量,它的作用类似C语言中的#define
  • TIMES 510-(\(-\)$) DB 0: 该指令指令经常出现在MBR中, 目的是为了除了最后的标志位0x55AA, 之前的填充为0

NSAM中的宏定义

  • 类似于C语言中的宏定义, 不过使用的是%号, 其他都是一样的: %include, %ifndef, %define, %ifdef,
  • 使用带有参数的宏定义
%macro macroname #(表示参数的个数)
mov [%1] ax ; %1表示第一个参数, 以此类推, %2, %3

%endmarco
上一篇:Linux编译安装MySQL


下一篇:神经网络