Assembly Language

不可视境界线最后变动于:2022年10月2日 下午

整这些有的没的不如看gas的官方文档

现在主要用到的就是gas, 所以整点gas基础的东西.

  • If the symbol begins with a letter the statement is an assembly language instruction

汇编语言伪指令(最要命的

  • 伪指令 (directive) 是嵌入源代码中的命令,由汇编器识别和执行。伪指令不在运行时执行,但是它们可以定义变量、宏和子程序;为内存段分配名称,执行许多其他与汇编器相关的日常任务。
  • 简单来说就是方便编程的指令

基本:

  • .data .code .stack 定义段(segment)
  • .model flat,stdcall它告诉汇编程序用的是哪一种存储模式
  • .END标记一个程序的结束

数据类型及伪指令

数据定义

类型 用法
BYTE 8 位无符号整数,B 代表字节
SBYTE 8 位有符号整数,S 代表有符号
WORD 16 位无符号整数
SWORD 16 位有符号整数
DWORD 32 位无符号整数,D 代表双(字)
SDWORD 32 位有符号整数,SD 代表有符号双(字)
FWORD 48 位整数(保护模式中的远指针)
QWORD 64 位整数,Q 代表四(字)
TBYTE 80 位(10 字节)整数,T 代表 10 字节
REAL4 32 位(4 字节)IEEE 短实数
REAL8 64 位(8 字节)IEEE 长实数
REAL10 80 位(10 字节)IEEE 扩展实数

还可以是传统数据定义伪指令,如下表所示。

伪指令 用法 伪指令 用法
DB 8位整数 DQ 64 位整数或实数
DW 16 位整数 DT 定义 80 位(10 字节)整数
DD 32 位整数或实数

初始化语句

1
[name] directive initializer [,initializer]...

如果希望不对变量进行初始化(随机分配数值),可以用符号 ? 作为初始值, 所有数值都由汇编器来转成二进制数据

  • BYTE and SBYTE

    • 多初始值定义数组
    1
    2
    3
    4
    5
    list BYTE 10,20,30,40
    #甚至可以:
    list BYTE 10,20,30,40
    BYTE 50,60,70,80
    BYTE 81,82,83,84
    • 定义字符串: 使用BYTE,
    1
    2
    3
    4
    5
    greeting1 BYTE "Good afternoon",0
    #也可以
    greeting1 BYTE "Welcome to the Encryption Demo program "
    BYTE "created by Kip Irvine.",0dh, 0ah
    #还可以使用backslash分行
    • DUP 操作符: 使用一个整数表达式作为计数器,为多个数据项分配存储空间
    1
    2
    3
    4
     BYTE 4 DUP ( "STACK" ) ; 20 个字节:
    #第一个数字是BYTE的个数, 第二个数字由DUP计算得出, 单位是字节
    #提供了一种方便的方式来初始化数组:
    array BYTE 5 DUP (?) ; 5 个数值,未初始化
  • WORD and SWORD, DWORD, SDWORD, QWORD,

  • 同BYTE和SBYTE

  • 剩下还有浮点类型, BCD数据等等, 不看了


  • .DATA ?伪指令声明未初始化数据。当定义大量未初始化数据时,.DATA ? 伪指令减少了编译程序的大小。

  • 等号=伪指令, 相当于宏定义一个数据, 可多次重复定义

  • 当前地址计数器:selfPtr DWORD $

  • 让汇编器计算数组长度:

    1
    2
    list BYTE 10,20,30,40
    ListSize = ($ - list) # 注意此时计算出来的是地址的差值, 所以单位是字节, 如果遇到WORD要注
  • EQU伪指令, 无法多次定义

    1
    2
    3
    name EQU expression    #必须是整数表达式
    name EQU symbol #任意一个用EQU或=定义过的符号
    name EQU <text> #直接文本替换, 最像#define, 也可用来定义实数
  • TEXTEQU 文本宏伪指令,

    1
    2
    3
    name TEXTEQU <text>            # 就是文本
    name TEXTEQU textmacro # 前面的文本宏
    name TEXTEQU %constExpr # 整数表达式

相关指令

操作数有 3 种基本类型:

  • 立即数——用数字文本表达式
  • 寄存器操作数——使用 CPU 内已命名的寄存器
  • 内存操作数——引用内存位置
操作数 说明
reg8 8 位通用寄存器:AH、AL、BH、BL、CH、CL、DH、DL
reg16 16 位通用寄存器:AX、BX、CX、DX、SI、DI、SP、BP
reg32 32 位通用寄存器:EAX、EEX、ECX、EDX、ESI、EDI、ESP、EBP
reg 通用寄存器
sreg 16 位段寄存器:CS、DS、SS、ES、FS、GS
imm 8 位、16 位或 32 位立即数
imm8 8 位立即数,字节型数值
imm16 16 位立即数,字类型数值
imm32 32 位立即数,双字型数值
reg/mem8 8 位操作数,可以是 8 位通用寄存器或内存字节
reg/mem16 16 位立即数,可以是 16 位通用寄存器或内存字
reg/mem32 32 位立即数,可以是 32 位通用寄存器或内存双字
mem 8位、16 位或 32 位内存操作数

4.9 OFFSET运算符 : 表示的是该数据标号距离数据段起始地址的距离

4.10 ALIGN伪指令 1,2,4,8,16字节对齐

4.11 PTR运算符

  • mov ax,WORD PTR myDouble, 把一个DWORD的低两字节传入ax(因为是小端法存储, 而且可用偏移来传入
    高两字节:mov ax,WORD PTR [myDouble+2])

  • 把两个小的移入大的:

    1
    2
    wordList WORD 5678h,1234h
    mov eax, DWORD PTR wordList

4.12 TYPE运算符 返回变量的大小

4.13 LENGTHOF运算符 计算数组中元素的个数, 如果数组占据多行, 只计算第一行

4.14 LABEL伪指令 可以插入一个标号,并定义它的大小属性,但是不为这个标号分配存储空间
LongValue LABEL DWORD 标识下一个地址开始的DWORD字节

4.15 间接寻址 特殊: inc BYTE PTR [esi] 要加指针的类型, 剩下的有很多, 详见网站

4.16 JMP和LOOP指令 这个loop集成了ECX以及其他一些指令, 要看的话详见网站

汇编语言过程

  • 压栈出栈, push&pop

  • PUSHFD 和 POPFD 指令: 压入和弹出EFLAGS寄存器

  • PUSHA (push all-16bits), PUSHAD (push all double-32bits), POPAD 和 POPA

  • PROC和ENDP :定义一个过程

    1
    2
    3
    4
    main PROC
    .
    .
    main ENDP
    • 标号只有过程中的有效, 不过也可以定义全局标号Destination::, 使用两个引号即可, 尽量少用
  • USES 运算符: 在PROC 伪指令一行后面指出当前过程要修改的寄存器, 汇编器在头尾自动生成push和pop指令, 只对汇编器有效

  • 链接库跳过

条件判断

操作 说明
AND 源操作数和目的操作数进行逻辑与操作
OR 源操作数和目的操作数进行逻辑或操作
XOR 源操作数和目的操作数进行逻辑异或操作
NOT 对目标操作数进行逻辑非操作
TEST 源操作数和目的操作数进行逻辑与操作,并适当地设置 CPU 标志位
  • 置位和清除零标志位、符号标志位、进位标志位和溢出标志位的方法
  • 汇编语言64位模式下的布尔指令:
    • 32 位操作数是一个特殊的情况,需要与其他大小操作数的情况分开考虑。
  • 条件跳转
    • 注意无符号数和有符号数的比较是不同的.

整数运算

  1. 汇编语言移位和循环移位指令简介

  2. 汇编语言SHL(左移)指令:将操作数逻辑左移一位

  3. 汇编语言SHR(右移)指令:将操作数逻辑右移一位

  4. 汇编语言SAL(算术左移)和SAR(算术右移)指令:将操作数左

  5. 汇编语言ROL(循环左移)指令:将操作数所有位都向左移

  6. 汇编语言ROR(循环右移)指令:将操作数所有位都向右移

  7. 汇编语言RCL(带进位循环左移)和RCR(带进位循环右移)指令

  8. 汇编语言SHLD(双精度左移)和SHRD(双精度右移)指令

  9. 汇编语言移位和循环移位的应用

  10. 汇编语言MUL指令:无符号数乘法

  11. 汇编语言IMUL指令:有符号数乘法

  12. 汇编语言GetMseconds:测量程序执行时间

  13. 汇编语言DIV指令:无符号除法

  14. 汇编语言IDICV指令:有符号数除法

  15. 使用汇编语言实现算术表达式[实例]

  16. 汇编语言ADC指令:带进位加法

  17. 汇编语言SBB指令:带借位减法

  18. 汇编语言ASCII和非压缩十进制运算

  19. 汇编语言AAA指令:调整ADD或ADC指令的二进制运算结果

  20. 汇编语言AAS指令:减法后的ASXII调整

  21. 汇编语言AAM(乘法后的ASCII调整)和AAD(除法之前的ASCII调整)指

  22. 汇编语言压缩十进制运算简介

  23. 汇编语言DAA指令:加法后的十进制调整

  24. 汇编语言DAS指令:减法后的十进制调整

汇编语言高级过程