汇编语言-基于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 main

3.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+9
  • 26.E5

十六进制实数:使用 IEEE 754协议编码,如 +1.0可表示为3F800000r

3.1.6-字符串

"I'm ok"`、`'He said:"Hello"'

3.1.7-保留字

特殊的字段,只能在特定情况下使用,如MOV指令

下图为MASM保留字

image-20220520164047543

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
类型用法
BYTE8位无符号整数, B代表字节
SBYTE8位有符号整数, s代表有符号
WORD16位无符号整数
SWORD16位有符号整数
DWORD32位无符号整数,D代表双(字)
SDWORD32位有符号整数, SD代表有符号双(字)
FWORD48位整数(保护模式中的远指针)
QWORD64位整数,Q代表四(字)
TBYTE80位(10字节)整数,T代表10字节
REAL432位(4字节)IEEE短实数
REAL864位(8字节) IEEE长实数
REAL1080位(10字节) IEEE扩展实数

3.10-编程练习

1-整数表达式计算

image-20220525103712381

; 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 main

2-符号整数常量

image-20220525105009364

; 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 main

3-数据定义

image-20220525105216758

4-符号文本常量

image-20220525105229294

5-AddTwoSum列表文件

image-20220525105240118

6-AddVariables程序

image-20220525105248318

4-数据传送、寻址、算术运算

4.2-加减法

4.2.6-受加减法影响的标志位

无符号标志位:零标志位、加法和减法进位标志、辅助进位标志

零标志位:运算结果是否为0,为零则置1,反之0

加法和减法进位标志:超过目标操作数存储大小(INC和DEC不会影响进位标志)

辅助进位标志:目的操作数位3有错位或进位

image-20220520182404448

奇偶标志位:偶数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 main

4.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 main

4.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 ;0040400Ch

4.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 main

4.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 main

5.9.2

6-条件处理

6.8-小结

6.8.8-消息加密

image-20220521011330654

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 main
EAX = 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 main
EAX = 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 main
EAX = 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 main
EAX = 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 main

Practice_3

3.1

image-20220520195759752

3.2

image-20220520195812809

3.3

image-20220520195822838

3.4

image-20220520195838235

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

image-20220520221834516

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

image-20220520222523314

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 main

4

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 main

5

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 main

6

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

image-20220520221120792

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