汇编语言-基于x86处理器
[toc]
1-基本概念
1.7-复习题
1.7.1-简答题
3-汇编语言基础
3.1-基本语言元素
3.1.1-第一个汇编语言程序
main PROC
mov eax ,5 ;将数字5送入eax寄存器
add eax,6;eax寄存器加6
INVOKE ExitProcess,0 ;程序结束
main ENDP上面这个程序不能运行,需要添加额外说明
; AddTwo.asm - adds two 32-bit integers.
; Chapter 3 example
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword现在程序可以正常运行了
添加变量
.data ; 此为数据区域
sum dword 0 ; 定义了名为 sum的变量,它将存储运算的和
; dword 限制sum的数据大小,但没有定义类型如 int、float等
.code
main PROC
mov eax ,5 ;将数字5送入eax寄存器
add eax,6 ;eax寄存器加6
mov sum,eax
INVOKE ExitProcess,0 ;程序结束
main ENDP
end main3.1.2-整型常量
| 表示 | 解释 |
|---|---|
| h | 十六进制 |
| q/o | 八进制 |
| d | 十进制 |
| b | 二进制 |
| r | 编码实数 |
| t | 十进制(备用) |
| y | 二进制(备用) |
以字母开头的16进制数必须为0开头,否则会被误认为标识符
3.1.3-实数常量
十进制实数表达式: {sign} [integer].[integer] [exponent]
其中
sign表示 正负exponent表示精确的位数,格式为:E{+,-}integer
如
2.+3.0-1.9E+926.E5
十六进制实数:使用 IEEE 754协议编码,如 +1.0可表示为3F800000r
3.1.6-字符串
"I'm ok"`、`'He said:"Hello"'3.1.7-保留字
特殊的字段,只能在特定情况下使用,如MOV指令
下图为MASM保留字

3.1.10-指令
| 指令 | 解释 | 例子 |
|---|---|---|
| MOV | 传送(分配)数值 | MOV eax, 0将eax设置为0 |
| ADD | 两值相加 | ADD, eax,10将eax加10 |
| SUB | 两值相减 | |
| MUL | 两值相乘 | |
| JMP | 跳到新位置 | top: … jmp top |
| CALL | 调用子程序 | call DumpMem执行DumpMen |
| imul | 做乘法并返回 | imul, eax,ebx,5相当于eax = ebx*5 |
| NOP | 什么也不干 |
3.1.11-AddSum程序
; AddTwo.asm - adds two 32-bit integers.
; Chapter 3 example
.386 ; 伪指令,表示其为32为程序,能访问32位寄存器和地址
.model flat,stdcall ; 选择程序运行模式:flat,
; 确定子程序调用规范:stdcall
.stack 4096 ; 运行时保留4096位字节的存储空间
ExitProcess proto,dwExitCode:dword
; 声明ExitProcess 函数的原型,它是一个标准的 Windows 服务。原型包含了函数名、PROTO关键字、一个逗号,以及一个输入参数列表。ExitProcess的输入参数名称为dwExitCode。可以将其看作为给Windows操作系统的返回值,返回值为零,则表示程序执行成功;而任何其他的整数值都表示了一个错误代码。因此,程序员可以将自己的汇编程序看作是被操作系统调用的子程序或过程。当程序准备结束时,它就调用 ExitProcess,并向操作系统返回一个整数以表示该程序运行良好。
.data
v1 byte 78H
v2 word 1234h
v3 dword 12345678h
.code
main proc
mov eax,0
mov al,v1
mov ax,v2
mov eax,v3
mov ax,0
invoke ExitProcess,0
main endp
end main| 类型 | 用法 |
|---|---|
| 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扩展实数 |
3.10-编程练习
1-整数表达式计算

; Chapter 3.10-q1 A = (A+B)-(C_D)
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
DumpRegs PROTO
.data
aval DWORD 1H
bval DWORD 123H
cval DWORD 24H
dval DWORD 56H
.code
main proc
mov eax,aval
mov ebx,bval
mov ecx,cval
mov edx,dval
add eax,ebx ; A = (A+B)
sub ecx,edx ; C = (C-D)
sub eax,ecx
call DumpRegs
invoke ExitProcess,0
main endp
end main2-符号整数常量

; Chapter 3.10-q1 A = (A+B)-(C_D)
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
DumpRegs PROTO
.data
monday equ 1H
tuesday equ 2H
wednesday equ 3H
thursday equ 4H
friday equ 5H
saturday equ 6H
sunday equ 7H
arr DWORD monday,tuesday,wednesday,thursday,friday,saturday,sunday
arr_len DWORD ($-arr)
.code
main proc
mov eax, arr_len
mov ebx, monday
call DumpRegs
invoke ExitProcess,0
main endp
end main3-数据定义

4-符号文本常量

5-AddTwoSum列表文件

6-AddVariables程序

4-数据传送、寻址、算术运算
4.2-加减法
4.2.6-受加减法影响的标志位
无符号标志位:零标志位、加法和减法进位标志、辅助进位标志
零标志位:运算结果是否为0,为零则置1,反之0
加法和减法进位标志:超过目标操作数存储大小(INC和DEC不会影响进位标志)
辅助进位标志:目的操作数位3有错位或进位

奇偶标志位:偶数1奇数0
4.2.7-AddSubTest程序
.data
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40
.code
main proc
; inc和dec
mov ax, 1000h
inc ax
dec ax
; Rval = -Xval + (Yval-Zval)
mov eax, Xval ; eax=26
neg eax ; eax = -26
mov ebx, Yval
sub ebx, Zval
add eax, ebx
mov Rval, eax
; 零标准位
mov cx,1
sub cx,1
mov ax,0ffffh
inc ax
; 符号标志位
mov cx,0
sub cx,1
mov ax, 7fffh
add ax,2
; 进位标志
mov ax,0ffh
add ax,1
; 溢出标志
mov ax, +127
add ax,1
mov ax, -128
sub ax,1
invoke ExitProcess,0
main endp
end main4.3-数据相关运算符和伪指令
4.3.1-OFFSET运算
OFFSET示例:
.data
bVal BYTE ?
cVal WORD ?
dVal DWORD ?
eVal DWORD ?假设 bvald的位置在00404000,则offset返回值将为00404000H
mov esi, OFFSET bval实现数组访问
.data
; 定义数组
myArray WORD 1, 2, 3, 4, 5
.code
main proc
; mvo esi myArray
mov esi, OFFSET myArray+1
mov esi, OFFSET myArray+2
mov esi, OFFSET myArray+3
mov esi, OFFSET myArray+4
invoke ExitProcess,0
main endp
end main实现大数组
.data
; 定义长为500的数组
bigArray DWORD 500 DUP(?)
pArray DWORD bigArray
; pArray指向bigArray的起始地址
.code
main proc
; mvo esi myArray
mov esi, OFFSET pArray
mov esi, OFFSET pArray+1
mov esi, OFFSET pArray+2
invoke ExitProcess,0
main endp
end main4.3.2-ALIGN指令
ALIGN指令将下一个变量对齐,方式根据参数而定,一般为 2^n^,表示下一个变量地址必须为其倍数,否则补零,以便CPU寻址
bVal BYTE ;00404000h
ALIGN 2
wVal WORD ;00404002h 而非 01h
bVal2 BYTE ;00404004h
ALIGN 4
dVal DWORD ;00404008h 而非 05h
dVa12 DWORD ;0040400Ch4.3.3-PTR指令
重写已被声明过的操作数的大小类型
.data
myDW DWORD 12345678H
myList WORD 4321h,8765h
.code
main proc
; mov ax,myDW
mov ax, WORD PTR myDW
mov eax,DWORD PTR myList
invoke ExitProcess,0
main endp
end main4.3.4-TYPE
返回字节数
4.3.5-LENGTHOF
返回数组长度
4.3.6-SIZEOF
返回LENGTHOF*TYPE
4.4-间接寻址
5-
5.9
5.9.1
include Irvine32.inc
.data
string BYTE "Decrypted: "
.code
main PROC
; 黄字蓝底
mov eax,yellow+(blue*16)
call SetTextColor
mov edx, offset string
call WriteString
call Crlf
mov eax,blue+(black*16)
call SetTextColor
mov edx, offset string
call WriteString
call Crlf
mov eax,red+(white*16)
call SetTextColor
mov edx, offset string
call WriteString
call Crlf
mov eax,yellow+(black*16)
call SetTextColor
mov edx, offset string
call WriteString
call Crlf
invoke ExitProcess,0
main ENDP
END main5.9.2
6-条件处理
6.8-小结
6.8.8-消息加密

Exercise
Assembly programming practice 1
a
Input following asm program and observe the result register and memory
; AddTwo.asm - adds two 32-bit integers.
; Chapter 3 example
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.code
main proc
mov eax,5
add eax,6
invoke ExitProcess,0
main endp
end mainEAX = 0000000B(11)
b
calculate 5*4+6, observe register, print the result on screen
;calculate 5*4+6, observe register, print the result on screen
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.code
main proc
mov eax,0
mov ecx,4
lp:
add eax,5
loop lp
add eax,6
invoke ExitProcess,0
main endp
end mainEAX = 0000001F
c
calculate 2^29^+40, 2^31^+1 observe the result
1.Calculate 2^29^+40
;calculate 5*4+6, observe register, print the result on screen
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.code
main proc
mov eax,1
mov ecx,29
lp:
add eax,eax
loop lp
add eax,40
invoke ExitProcess,0
main endp
end mainEAX = 20000028
2.Calculate 2^31^+1
;calculate 5*4+6, observe register, print the result on screen
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.code
main proc
mov eax,1
mov ecx,31
lp:
add eax,eax
loop lp
add eax,1
invoke ExitProcess,0
main endp
end mainEAX = 80000001
d
Input the following code from chapter 3 in book (call DumpRegs; display the registers; call WriteInt;display integer)
; AddSubAlt.asm
; This program adds and subtracts 32-bit integers.
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
DumpRegs PROTO
.code
main PROC
mov eax,10000h ; EAX = 10000h
add eax,40000h ; EAX = 50000h
sub eax,20000h ; EAX = 30000h
call DumpRegs
INVOKE ExitProcess,0
main ENDP
END main
EAX=00030000 EBX=01187000 ECX=00DA10AA EDX=00DA10AA
ESI=00DA10AA EDI=00DA10AA EBP=012FFA9C ESP=012FFA90
EIP=00DA3670 EFL=00000206 CF=0 SF=0 ZF=0 OF=0 AF=0 PF=1
e
Run a program of 3.4.10 in the book(p.84)
; AddSubAlt.asm
; This program adds and subtracts 32-bit integers.
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
DumpRegs PROTO
.data
firstVal DWORD 20002000H
secondVal DWORD 11111111H
thirdVal DWORD 22222222H
sum DWORD 0
.code
main PROC
mov eax, 0
add eax, firstVal
add eax, secondVal
add eax, thirdVal
call DumpRegs
INVOKE ExitProcess,0
main ENDP
END main
EAX=53335333 EBX=006CC000 ECX=00BA10AA EDX=00BA10AA
ESI=00BA10AA EDI=00BA10AA EBP=005DFB28 ESP=005DFB1C
EIP=00BA3678 EFL=00000206 CF=0 SF=0 ZF=0 OF=0 AF=0 PF=1
f-Hello World
Write an asm program to display “Hello world”
; 32-Bit Intel Protected Mode Programming
; KIP IRVINE Assembly Language for x86 / Intel-Based Computers.
;
.386
.model flat,stdcall
.stack 4096
; DEFINE/DECLARE necessary WIN32 constants, functions etc.
;------------------------------------------------------------
; Win32 Console handles
STD_OUTPUT_HANDLE EQU -11 ; predefined Win API constant
; ALIAS : The following Win32 API functions have an
; extra "A" at the end of their name,
; so they are redefined here with text macros:
WriteConsole EQU <WriteConsoleA>
; FUNCTION PROTOTYPES
; -------------------------------------------------------------
ExitProcess PROTO, ; exit program
dwExitCode:DWORD ; return code
GetStdHandle PROTO, ; get standard handle
nStdHandle:DWORD ; type of console handle
WriteConsole PROTO, ; write a buffer to the console
handle:DWORD, ; output handle
lpBuffer:PTR BYTE, ; pointer to buffer
nNumberOfBytesToWrite:DWORD, ; size of buffer
lpNumberOfBytesWritten:PTR DWORD, ; num bytes written
lpReserved:DWORD ; (not used)
; User Defined Data Section
; ---------------------------------------------------------------
.data
mesg1 BYTE "Hello world!",0dh,0ah,0
sizeMesg1 = ($-mesg1)-1 ; ex-cluding the sign bit
BytesWritten DWORD 0
ConsoleOutHandle DWORD 0
.code
main proc
; Get Standart Output Handle
INVOKE GetStdHandle, STD_OUTPUT_HANDLE ; Get a handle to console SCREEN.
mov ConsoleOutHandle, eax
; Write Message to the Handle => CONSOLE
INVOKE WriteConsole, ConsoleOutHandle, ADDR mesg1, (LENGTHOF mesg1)-1, ADDR BytesWritten, 0
invoke ExitProcess,0
main endp
;-------------------------------------------------------------------
end main
精简版
INCLUDE Irvine32.inc
.code
msg BYTE "Hello World", 0
main PROC
mov edx, offset msg
call WriteString
exit
main ENDP
END mainPractice_3
3.1

3.2

3.3

3.4

3.5
Using the AddTwoo program from Section 3.2 as a reference, write a program that calculates the following expression, using registers: A = (A + B) - (C + D). Assign integer values to the EAX, EBX, ECX, and EDX registers
; AddSubAlt.asm
; This program adds and subtracts 32-bit integers.
.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
DumpRegs PROTO
.data
aVal DWORD 20002000H
bVal DWORD 11111111H
cVal DWORD 22222222H
dVal DWORD 12345678H
sum DWORD 0
.code
; A = (A + B) - (C + D)
main PROC
; A+B
mov eax, aVal
add eax, bVal
;C+D
mov ecx, cVal
add ecx, dVal
; eax = (A+B)-(C+D)
sub eax,ecx
mov aVal, eax
call DumpRegs
INVOKE ExitProcess,0
main ENDP
END main
EAX=FCBAB877 EBX=00D04000 ECX=3456789A EDX=005110AA
ESI=005110AA EDI=005110AA EBP=00EFFB00 ESP=00EFFAF4
EIP=0051367F EFL=00000297 CF=1 SF=1 ZF=0 OF=0 AF=1 PF=1
3.6
Using the AddSub program from Section 3.2, you can add a data segment containing several doubleword variables and store the final result into memory
Practice_4
Practice_5
1- BetterRandomRange Procedure
The RandomRange procedure from the Irvine32 library generates a pseudorandom integer between 0 and N - 1. Your task is to create an improved version that generates an integer between M and N-1. Let the caller pass M in EBX and N in EAX. If we call the procedure BetterRandomRange, the following code is a sample test:
mov ebx,-300 ; lower bound
mov eax,100 ; upper bound
call BetterRandomRange Write a short test program that calls BetterRandomRange from a loop that repeats 50 times. Display each randomly generated value.
INCLUDE Irvine32.inc
.data
.code
main PROC
call Clrscr
mov eax, -300
mov ebx, 100
mov ecx, 50
L1:
push eax ; doesn't change range
push ebx
call BetterRandomRange
pop ebx
pop eax
Loop L1
call WaitMsg
exit
main ENDP
BetterRandomRange PROC
sub ebx, eax ;mov 400 to ebx
xchg ebx, eax ;random works with eax
call RandomRange ; generate random int
neg ebx
sub eax, ebx ;sub 300 from eax to define range
call WriteInt ; write signed decimal
call Crlf
ret
BetterRandomRange ENDP
END main
2-Random Strings
Write a program that generates and displays 20 random strings, each consisting of 10 capital letters {A..Z}.
INCLUDE Irvine32.inc
.data
ecxCopy DWORD ?
outTime DWORD 20
innerTime DWORD 10
.code
main PROC
call Clrscr
mov eax, 'A'
mov ebx, 'Z'
mov ecx, outTime
loopOut:
mov ecxCopy,ecx
mov ecx, innerTime
loopInner:
push eax ; doesn't change range
push ebx
call BetterRandomRange
pop ebx
pop eax
loop loopInner
call Crlf
mov ecx,ecxCopy
Loop loopOut
call WaitMsg
exit
main ENDP
BetterRandomRange PROC
sub ebx, eax ;mov 400 to ebx
xchg ebx, eax ;random works with eax
call RandomRange ; generate random int
neg ebx
sub eax, ebx ;sub 300 from eax to define range
call WriteChar ; write char
ret
BetterRandomRange ENDP
END main
Exercise 7
1
Write a sequence of instructions that shift three memory bytes to the right by 1 bit position. Use the following data definition: Byte Array BYTE 81h,20h,33h
2
Write a sequence of instructions that shift three memory words to the left by 1 bit position. Use the following data definition: Byte Array WORD 810Dh, 0C064h,93ABh
3
Write ASM instructions that calculate EAX * 24 using binary multiplication
include Irvine32.inc
.code
main proc
mov eax, 2
mov ebx, 24
mul ebx
call DumpRegs
invoke ExitProcess,0
main endp
end main4
Write instructions that multiply 5 by 3 and store the result in a 16-bit variable val1.
include Irvine32.inc
.data
; Byte Array WORD 810Dh, 0C064h,93ABh
val1 WORD 0
.code
main proc
mov ax, 5
mov bx, 3
mul bx
mov val1, ax
call DumpRegs
invoke ExitProcess,0
main endp
end main5
Write instructions that divide 276 by 10 and store the result in a 16-bit variable val1.
include Irvine32.inc
.data
; Byte Array WORD 810Dh, 0C064h,93ABh
val1 WORD 0
.code
main proc
mov dx, 0
mov ax, 256
mov bx, 10
div bx
mov val1, ax
call DumpRegs
invoke ExitProcess,0
main endp
end main6
Implement the following C++ expression in assembly language, using 32-bit unsigned operands: val1 = (val2 * val3) / (val4 - 3)
7
Implement the following C++ expression in assembly language, using 32-bit signed operands: (val2 / val3) * (val1 + val2)
8
Encryption Using Rotate Operations Write a program that performs simple encryption by rotating each plaintext byte a varying number of positions in different directions. For example, in the following array that represents the encryption key, a negative value indicates a rotation to the left and a positive value indicates a rotation to the right. The integer in each position indicates the magnitude of the rotation: key BYTE 2, 4, 1, 0, 3, 5, 2, 4, 4, 6 Your program should loop through a plaintext message and align the key to the first 10 bytes of the message. Rotate each plaintext byte by the amount indicated by its matching key array value. Then, align the key to the next 10 bytes of the message and repeat the process.
其他有意思的代码
自己的
循环打印A-Z,a-z
TITLE A to Z
;loop that prints from a to z & z to a
INCLUDE Irvine32.inc
.code
small BYTE 'a',0
big BYTE 'A',0
main PROC
mov al, small
mov ecx, 26
lp1:
call WriteChar
add al,1
loop lp1
call Crlf
mov ecx, 26
mov al, big
lp2:
call WriteChar
add al,1
loop lp2
exit
main ENDP
END main
One Time Cipher
别人的
Encrypt
; Encryption Program (Encrypt.asm)
; This program demonstrates simple symmetric
; encryption using the XOR instruction.
INCLUDE Irvine32.inc
KEY = 239 ; any value between 1-255
BUFMAX = 128 ; maximum buffer size
.data
sPrompt BYTE "Enter the plain text: ",0
sEncrypt BYTE "Cipher text: ",0
sDecrypt BYTE "Decrypted: ",0
buffer BYTE BUFMAX+1 DUP(0)
bufSize DWORD ?
.code
main PROC
call InputTheString ; input the plain text
call TranslateBuffer ; encrypt the buffer
mov edx,OFFSET sEncrypt ; display encrypted message
call DisplayMessage
call TranslateBuffer ; decrypt the buffer
mov edx,OFFSET sDecrypt ; display decrypted message
call DisplayMessage
exit
main ENDP
;-----------------------------------------------------
InputTheString PROC
;
; Prompts user for a plaintext string. Saves the string
; and its length.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov edx,OFFSET sPrompt ; display a prompt
call WriteString
mov ecx,BUFMAX ; maximum character count
mov edx,OFFSET buffer ; point to the buffer
call ReadString ; input the string
mov bufSize,eax ; save the length
call Crlf
popad
ret
InputTheString ENDP
;-----------------------------------------------------
DisplayMessage PROC
;
; Displays the encrypted or decrypted message.
; Receives: EDX points to the message
; Returns: nothing
;-----------------------------------------------------
pushad
call WriteString
mov edx,OFFSET buffer ; display the buffer
call WriteString
call Crlf
call Crlf
popad
ret
DisplayMessage ENDP
;-----------------------------------------------------
TranslateBuffer PROC
;
; Translates the string by exclusive-ORing each
; byte with the encryption key byte.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov ecx,bufSize ; loop counter
mov esi,0 ; index 0 in buffer
L1:
xor buffer[esi],KEY ; translate a byte
inc esi ; point to next byte
loop L1
popad
ret
TranslateBuffer ENDP
END main