汇编语言基础:
整数常量与进制表达(integer constants)
Synopsis:[{+| −}]digits[radix]
正或者符号 数字 基数
基数(进制)表达表
h Hexadecimal 十六进制
b Binary 二进制
d Decimal 十进制
q/o Octal 八进制
r Encoded real
t Decimal(alternate)
y Binary (alternate)
例子:
26 Decimal 42o Octal
26d Decimal 1Ah Hexadecimal
11010011b Binary 0A3hHexadecimal
42q Octal
表达式运算符与优先级:
实数常量:
[sign]integer.[integer][exponent]
例子:
2.
+3.0
-44.2E+05
26.E5
字符常量:
是用单引号或者双引号括起来的单个字符常量
例子:
'A'
"d"
字符串常量:
是以单引号或者双引号括起来的多个字符(字符串)的常量
例子:
'ABC'
'X'
"Good night,Gracie"
'4096'
如果显示字符串时需要显示双引号 为了不让编译器歧义 可以:
"This isn't atest"
'Say "Goodnight," Gracie'
标示符(identifier):
大小写随意
可以是任意从1-247的字符
第一个字符必须是字母后面可以跟字母或者数字
所有标示符不能跟keyword重名(ex:mov,sub,byte)
伪指令(directives)->这个翻译很怪异的说
“A Directive is a command embeddedin the source code that is recognized and acted upon by the
assembler.Directives do not execute at runtime. Directives can define variables, macros,and
procedures.They can assign names to memory segments and perform many other housekeeping
tasksrelated to the assembler.”
伪指令内嵌在源代码中,且被汇编器执行和认可。伪指令不在运行时执行… 伪指令可以定义变量 宏和过程
大小写不明感.data.DATA和.Data是一样的
“Thefollowing example helps to show the difference between directives andinstructions. The
DWORDdirective tells the assembler to reserve space in the program for a doublewordvariable.
TheMOV instruction, on the other hand, executes at runtime, copying the contentsofmyVar tothe EAXregister:“
下面的例子帮助我们区分伪指令和真正的指令,
伪指令->DWORD 告诉汇编器给myVar这个2字节变量预留空间,而真正的mov指令在运行时把变量MyVar的内容复制给EAX寄存器…
myVar DWORD 26 ; DWORDdirective
mov eax,myVar ; MOVinstruction
Defining Segments(定义段)
Oneimportant function of assembler directives is to define program sections, orsegments.
The .DATA directive identifies the area of aprogram containing variables:(数据区域)
.data
The.CODE directive identifies the area of a program containing executableinstructions:(代码区域)
.code
The.STACK directive identifies the area of a program holding the runtime stack,setting its size:(栈区域)
.stack 100h
AppendixA contains a useful reference for MASM directives and operators.
真正的指令(instructions)
•Label (optional)
•Instruction mnemonic (required)
• Operand(s) (usually required)
• Comment (optional)
syntax:
[label:]mnemonic[operands] [;comment]
标号:分数据标号和代码标号
数据标号:
array DWORD 1024, 2048
DWORD 4096, 8192
记录了变量array的第一个数字地址:1024如果想trace 下一个地址需要加offset(一般间隔2-4这种 address map 会用--)
代码表好:这个比较像c里面的goto语令
[label:]
target:
mov ax,bx
...
jmp target
语令jmp(跳转)可以跳转到target那里
指令助记符(instruction mnemonics)有助于记忆的语令:
mov Move (assign) one value to another 移动 赋值
add Add two values 相加
sub Subtract one value from another 相减
mul Multiply two values 相乘
jmp Jump to a new location 跳转
call Call a procedure 调用
Operands Assembly language instructions can have between zero and threeoperands, each
ofwhich can be a register, memory operand, constant expression, or input-outputport.
操作数 每个指令可以 有0-3个的操作数作为参数
一般第一个参数或者是操作数是目的地 第二个或和第三个是源头
例子:
stc ; set Carry flag
inc eax ; add 1 to EAX
mov count,ebx ; moveEBX to count
imul eax,ebx,5
注解:
用“;”分号后面来表述注解
注解块:
COMMENT !
This line is a comment.
This line is also acomment.
!
“!”可以用别的符号来代替
空操作(NOP no operation)
Ittakes up 1 byte of program storage and doesn’t do any work. It is sometimesused by compilers and assemblers to align code to even-address boundaries.
汇编-链接-执行 圈
终于打重头戏了--
定义数据:
[name]directive initializer [,initializer]...
变量名 伪指令 初始化 逗号 继续初始化
例子:count DWORD 12345
内部数据类型(比较重要)
遗留产物:
Initializer At least one initializer is required in a data definition, even if itis zero. Additional initializers,
ifany, are separated by commas.
初始化数据至少一个多个用逗号分隔
If multipleinitializers are used in the same data definition, its label refersonlyto theoffset of the
first initializer.
例子:
List BYTE 10,20,30,40
BYTE50,60,70,80
BYTE81,82,83,84
初始化数据类型,基数可以混用(这个与高级语言不一样的地方)
List1和list2是一样的
list1 BYTE 10, 32, 41h,00100010b
list2 BYTE 0Ah, 20h,'A', 22h
定义字符串:
定义字符串是个特例不需要用逗号隔开 因为那样做太痛苦
但是句尾需要用,0来完结(NULL)
例子:
greeting1 BYTE"Good afternoon",0
greeting2 BYTE 'Goodnight',0
greeting1 BYTE"Welcome to the Encryption Demo program "
BYTE "created byKip Irvine.",0dh,0ah
BYTE "If you wishto modify this program, please "
BYTE "send me acopy.",0dh,0ah,0
0dh,0ah 表示\r\n 换行
greeting1 \
BYTE "Welcome tothe Encryption Demo program "
“\”表示上行和下一行是一起的
DUP Operator(给变量分配空间)
伪代码 count DUP (size)——> count*size 个空间
BYTE 20 DUP(0) ; 20bytes, all equal to zero
BYTE 20 DUP(?) ; 20bytes, uninitialized
BYTE 4 DUP("STACK") ; 20 bytes:"STACKSTACKSTACKSTACK"
小尾顺序:
最低位放在最低的地址上…
未初始化变量—>”.Data?”
.data
smallArray DWORD 10DUP(0) ; 40 bytes
.data?
bigArray DWORD 5000DUP(?) ; 20,000 bytes, not initialized
符号常量:
等号伪语令 这个跟c语言的define 宏比较像
Syntax:
name = expression
COUNT = 500
好处在于 如果后续想改这个被用于多处变量的数值 只需要改这个宏就行了
等号伪语令可以反复重新定义赋值:
COUNT = 5
mov al,COUNT ; AL = 5
COUNT = 10
mov al,COUNT ; AL = 10
COUNT = 100
mov al,COUNT ; AL = 100
计算数组长度或者字符串长度:
“$”这个符号告诉我们目前(现在)的地址位置
例子:
list BYTE 10,20,30,40
ListSize = ($ - list)
myString BYTE"This is a long string, containing"
BYTE "any numberof characters"
myString_len = ($ − myString)
list WORD1000h,2000h,3000h,4000h
ListSize = ($ − list)/ 2
这里除以2是因为单位统一为byte(字节)而WORD是双字节
计算长度的语句紧接着定义的数据因为“$”是当今地址符,
以下例子是错误的:
list BYTE 10,20,30,40
var2 BYTE 20 DUP(?)
ListSize = ($ - list)
EQU Directive:
nameEQU expression
nameEQU symbol
nameEQU <text>
PI EQU <3.1416>
pressKey EQU<"Press any key to continue...",0>
matrix1 EQU 10 * 10
matrix2 EQU <10 *10>
.data
M1 WORD matrix1
M2 WORD matrix2
这两个 m1 m2 不等价— 一个是整数 一个是字符串
EQU伪代码不能重定义和赋值!
TEXTEQU Directive
Syntax:
nameTEXTEQU <text>
nameTEXTEQU textmacro
nameTEXTEQU %constExpr
例子:
rowSize = 5
count TEXTEQU %(rowSize* 2)
move TEXTEQU<mov>
setupAL TEXTEQU<move al,count>
TEXTEQU伪代码可以重定义