本次学习记录参考书籍《汇编语言程序设计》 主编:雷金辉 副主编:李心一,杨志翔 配合学习8086的汇编原理特别推荐这一本书 佩服老一代学者清晰的逻辑和干练的语言组织
寄存器 8086/8088内部有14个16位寄存器,可分为三类
通用寄存器8个
AX[AH,AL]累加器
BX[BH,BL]基址寄存器
CX[CH,CL]计数寄存器,在循环控制指令中会指定操作该寄存器
DX[DH,DL]数据寄存器
SP堆栈指针寄存器。在使用堆栈操作指令(push, pop)对堆栈操作的时候会自动地将sp内容进行加减操作
BP基址寄存器通常用来存放操作数在堆栈段内的偏移地址
SI源变址(偏移地址)寄存器
DI目的变址寄存器 这两个寄存器在串操作指令中用来进行字符操作
段寄存器4个
CS代码段寄存器,存放当前代码运行的段基址 与IP寄存器结合定位代码位置
DS数据段基址
SS堆栈段基址,配合SP对堆栈进行操作配合SI进行串的操作
ES附加段基址,配合DI进行串的操作
指令控制寄存器 IP存放下一条要读取的指令在代码段中的偏移地址 FLAGS 是一个16位的寄存器,但是只用了其中的9位,包括其中的6个状态寄存器和3个控制标志位
CF进位借位标志
PF奇偶标志位:当指令执行结果的低8位中含有偶数个1时PF=1否则为0
AF辅助进位借位标志
ZF零标志位,当运算结果为0时该标志位=1否则=0
SF符号标志位与运算结果的最高位相同
OF溢出标志位
TF陷阱标志位
IF中断允许标志位,若将该为置为1表示可以接受外部从INTR引脚上发来的中断请求
DF方向标志位,若将改为置为1串操作按减地址方向进行
程序结构 一个程序是由若干逻辑堆栈段,逻辑数据段,逻辑附加段,逻辑代码段构成,每种段可以有多个,但是一个程序的最少组成是一个代码段
寻址方式 参考博客【MASM汇编语言快速入门】寻址方式速查表_masm 怎么用al间接寻址-CSDN博客
——————25.07.30——————-
nasm汇编介绍 在8086平台上使用的编译工具有masm, tasm, nasm, openwatcom 前三者都是汇编语言编译工具,而openwatcom则是专注于c在硬件平台上的优化,其wasm汇编工具则是兼容masm 此次的8086开发我选择使用nasm, 其中的一个优点是不需要像masm 这样复杂的链接步骤,且其中的一些伪指令可以非常方便的组织 内存中的代码以及数据。
nasm工具使用语法 1 2 3 4 5 6 7 8 9 10 nasm -f <format> <filename> [-o output] [-l listing file] -format bin binary file 纯机器码文件 elf executable and linkable formate 现代链接格式,linux以及unix平台上面的标准格式 coff common object file formate 传统链接格式,早期windows系统的标准格式 -o 用于指定输出文件名 -l nasm在编译代码的同时生成一个可读的列表文件可以显示源代码, 每条指令对应的机器码以及所在内存中的地址,
-L用于开启特定的列表功能 比如 -Ld 可以讲16进制以及重复次数使用10进制表示
类似的功能还有 很多 并且nasm还支持在源代码中动态的打开以及关闭列表功能
1 2 3 4 5 6 7 8 9 10 11 12 13 ; ... some normal code ... ; 启用预处理(e)和宏展开(m)的列表输出 %pragma list options +em ; === 这里是你想重点分析的复杂宏调用 === my_complex_macro(arg1, arg2) ; ======================================= ; 分析完毕,关闭这些选项,恢复默认状态 %pragma list options -em ; ... a lot of other code ...
类似的还有很多可选项用于优化代码报告错误等
case sensitive 与masm不同的是 nasm是区分大小写的
大小写不同的lable指代的地址是不同的
memory referenct NASM的内存引用设计的也不同
1 2 3 4 5 foo equ 1 bar dw 2 mov ax foo ;常量 将1移动到ax中 mov ax bar ;变量将bar的偏移地址移动到ax中
NASM Doesn’t Store Variable Types nasm并不会记忆变量类型 在使用变量的时候必须指明变量的长度。
NASM不支持内存管理模型 不同于masm, nasm不会自动处理near call, far call
nasm语法 nasm use backslash(\) as the line continue character.
nasm对空格很宽松 NASM places no restrictions on white space within a line: labels may have white space before them, or instructions may have no space before them, or anything.
对于标签后的冒号也很宽松 The colon after a label is also optional.NASM 提供了一个命令行选项 -w+orphan-labels
,它会在标签定义没有冒号时发出警告。
nasm的标签可是使用字母数字下划线,$, #, @, ~, .,以及? 但是只有字母数字下划线 ., ?可以作为标签的起始位 nasm中标识符的最大长度为40959(但是应该没有人会起这么长的名字吧)
DX for declaring initialized data 1 2 3 4 5 6 7 8 9 10 11 12 13 db 0x55 ; just the byte 0x55 db 0x55,0x56,0x57 ; three bytes in succession db 'a',0x55 ; character constants are OK db 'hello',13,10,'$' ; so are string constants dw 0x1234 ; 0x34 0x12 dw 'a' ; 0x61 0x00 (it's just a number) dw 'ab' ; 0x61 0x62 (character constant) dw 'abc' ; 0x61 0x62 0x63 0x00 (string) dd 0x12345678 ; 0x78 0x56 0x34 0x12 dd 1.234567e20 ; floating-point constant dq 0x123456789abcdef0 ; eight byte constant dq 1.234567e20 ; double-precision float dt 1.234567e20 ; extended-precision float
RESB
and Friends: Declaring Uninitialized Dataresb 预留一个字节的空间
resw 预留两个字节空间(16b)
resd 预留四个字节的空间
resq 预留8个字节的空间 语法
1 2 3 4 5 6 7 8 9 lable: RESx num For example: buffer: resb 64 ; reserve 64 bytes wordvar: resw 1 ; reserve a word realarray resq 10 ; array of ten reals ymmval: resy 1 ; one YMM register zmmvals: resz 32 ; 32 ZMM registers
TIMES
: Repeating Instructions or Data
有效地址计算 因为 nasm的变量本身代表的意思就是变量的偏移地址
1 2 3 4 wordvar dw 123 mov ax,[wordvar] mov ax,[wordvar+1] mov ax,[es:wordvar+bx]
numeric constant 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 mov ax,200 ; decimal mov ax,0200 ; still decimal mov ax,0200d ; explicitly decimal mov ax,0d200 ; also decimal mov ax,0c8h ; hex mov ax,$0c8 ; hex again: the 0 is required mov ax,0xc8 ; hex yet again mov ax,0hc8 ; still hex mov ax,310q ; octal mov ax,310o ; octal again mov ax,0o310 ; octal yet again mov ax,0q310 ; octal yet again mov ax,11001000b ; binary mov ax,1100_1000b ; same binary constant mov ax,1100_1000y ; same binary constant once more mov ax,0b1100_1000 ; same binary constant yet again mov ax,0y1100_1000 ; same binary constant yet again
字符串使用 字符串可是使用单引号,双引号,反引号 字符串中需要转义的字符如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 \' single quote (') \" double quote (") \` backquote (`) \\ backslash (\) \? question mark (?) \a BEL (ASCII 7) \b BS (ASCII 8) \t TAB (ASCII 9) \n LF (ASCII 10) \v VT (ASCII 11) \f FF (ASCII 12) \r CR (ASCII 13) \e ESC (ASCII 27) \377 Up to 3 octal digits - literal byte \xFF Up to 2 hexadecimal digits - literal byte \u1234 4 hexadecimal digits - Unicode character \U12345678 8 hexadecimal digits - Unicode character
一个字符最高有8个字节长