Assembly Language for x86 Processors Part03

Assembly Language for x86 Processors Part03

本文是 Kip·Irvine 所写的 Assembly Langrage for x86 Processors (Seventh Edition) 第三章节的小结以及个人对章节编程习题的解答

图片[1]-Assembly Language for x86 Processors Part03

1 本章小节

整型常量表达式是算术表达式,包括了整数常量、符号常量和算术运算符。优先级是指当表达式有两个或更多运算符时,运算符的隐含顺序。

字符常量是用引号括起来的单个字符。汇编器把字符转换成一个字节,其中包含的是该字符的二进制 ASCII 码。字符串常量是用引号括起来的字符序列,可以选择用空字节标记结束。

汇编语言有一组保留字,它们含义特殊且只能用于正确的上下文中。标识符是程序员选择的名称,用于标识变量、符号常量、子程序和代码标号。不能用保留字作标识符。

伪指令是嵌在源代码中的命令,由汇编器进行转换。指令是源代码语句,由处理器在运行时执行。指令助记符是短关键字,用于标识指令执行的操作。标号是一种标识符,用作指令或数据的位置标记。

操作数是传递给指令的数据。一条汇编指令有 0 ~ 3 个操作数,每一个都可以是寄存器、内存操作数、整数表达式或输入输出端口号。

程序包括了逻辑段,名称分别为代码段、数据段和堆栈段。代码段包含了可执行指令;堆栈段包含了子程序参数、局部变量和返回地址;数据段包含了变量。

源文件包含了汇编语言语句。列表文件包含了程序源代码的副本,再加上行号、偏移地址、翻译的机器代码和符号表,适合打印。源文件用文本编辑器创建。汇编器是一种程序,它读取源文件,并生成目标文件和列表文件。链接器也是一种程序,它读取了一个或多个目标文件,并生成可执行文件。后者由操作系统加载器来执行。

MASM 识别内容数据类型,每一种类型都描述了一组数值,这些数值能分配给指定类型的变量和表达式:

  • BYTE 和 SBYTE 定义 8 位变量
  • WORD 和 SWORD 定义 16 位变量
  • DWORD 和 SDWORD 定义 32 位变量
  • QWORD 和 TBYTE 分别定义 8 字节和 10 字节变量
  • REAL4、REAL8 和 REAL10 分别定义 4 字节、8 字节和 10 字节实数变量

数据定义语句为变量预留内存空间,并可以选择性地给变量分配一个名称。如果一个数据定义有多个初始值,那么它的标号仅指向第一个初始值的偏移量。创建字符串数据定义时,要用引号把字符序列括起来。DUP 运算符用常量表达式作为计数器,生成重复的存储分配。当前地址计数器运算符 ($) 用于地址计算表达式。

x86 处理器用小端顺序在内存中存取数据:变量的最低有效字节存储在其起始 (最低) 地址中。

符号常量 (或符号定义) 把标识符与一个整数或文本表达式连接起来。有 3 个伪指令能够定义符号常量:

  • 等号伪指令 (=) 连接符号名称与整数常量表达式
  • EQU 和 TESTEQU 伪指令连接符号与整数常量表达式或一些任意的文本

2 编程练习

整数表达式的计算

参考 3.2 节的程序 AddTwo,编写程序,利用寄存器计算表达式:A = (A + B) – (C – D)。整数值分配给寄存器 EAX、EBX、ECX 和 EDX。

.386
.model flat, stdcall
.stack 4096

ExitProcess PROTO, dwExitCode: DWORD

.data
A_ DWORD 1
B_ DWORD 2
C_ DWORD 3
D_ DWORD 4

.code
main PROC
    mov eax, A_
    mov ebx, B_
    mov ecx, C_
    mov edx, D_
    add eax, ebx
    sub ecx, edx
    sub eax, ecx
    
    INVOKE ExitProcess, 0
main ENDP
END main

符号整数常量

编写程序,为一周七天定义符号常量。创建一个数组变量,用这些符号常量作为其初始值。

.386
.model flat, stdcall
.stack 4096

ExitProcess PROTO, dwExitCode: DWORD

.data
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
Sun = 7

Week DWORD Mon, Tue, Wed, Thu, Fri, Sat, Sun

.code
main PROC
    INVOKE ExitProcess, 0
main ENDP
END main

数据定义

编写程序,对 3.4 节表 3-2 中列出的每一个数据类型进行定义,并将每个变量都初始化为与其类型一致的数值。

.386
.model flat, stdcall
.stack 4096

ExitProcess PROTO, dwExitCode: DWORD

.data
; BYTE SBYTE
value1 BYTE 'A'
value2 BYTE 0
value3 BYTE 255
value4 SBYTE -128
value5 SBYTE 127

; TBYTE
intVal TBYTE 80000000000000001234h

; WORD SWORD
word1 WORD 65535
word2 SWORD -32768

; DWORD SDWORD
dword1 DWORD 12345678h
dword2 SDWORD -2147483648

; FWORD QWORD
fword1 FWORD 123456781234h
qword1 QWORD 1234567812345678h

; REAL4 REAL8 REAL10
reVal1 REAL4 -1.2
reVal2 REAL8 3.2E-260
reVal3 REAL10 4.6E+4096

.code
main PROC
    INVOKE ExitProcess, 0
main ENDP
END main

符号文本常量

编写程序,定义几个字符串文本 (引号之间的字符) 的符号名称,并将每个符号名称都用于变量定义

.386
.model flat, stdcall
.stack 4096

ExitProcess PROTO, dwExitCode: DWORD

text1 TEXTEQU <"text1">
text2 TEXTEQU <"test2">

.data
val1 BYTE text1
val2 BYTE text2

.code
main PROC  
    INVOKE ExitProcess, 0
main ENDP
END mainv

AddTwoSum 的列表文件

生成 AddTwoSum 程序的列表文件,为每条指令机器代码字节编写说明。某些字节值的含义需要猜测。

				.386
				.model flat, stdcall
				.stack 4096

				ExitProcess PROTO, dwExitCode: DWORD

 00000000			.data
 00000000 00000000		sum DWORD 0

 00000000			.code
 00000000			main PROC
 00000000  B8 00000005		    mov eax, 5
 00000005  83 C0 06		    add eax, 6
 00000008  A3 00000000 R	    mov sum, eax

				    INVOKE ExitProcess, 0
 0000000D  6A 00	   *	    push   +000000000h
 0000000F  E8 00000000 E   *	    call   ExitProcess
 00000014			main ENDP
				END main

Segments and Groups:

                N a m e                 Size     Length   Align   Combine Class

FLAT . . . . . . . . . . . . . .	GROUP
STACK  . . . . . . . . . . . . .	32 Bit	 00001000 DWord	  Stack	  'STACK'	 
_DATA  . . . . . . . . . . . . .	32 Bit	 00000004 DWord	  Public  'DATA'	
_TEXT  . . . . . . . . . . . . .	32 Bit	 00000014 DWord	  Public  'CODE'	


Procedures, parameters, and locals:

                N a m e                 Type     Value    Attr

ExitProcess  . . . . . . . . . .	P Near	 00000000 FLAT	Length= 00000000 External STDCALL
main . . . . . . . . . . . . . .	P Near	 00000000 _TEXT	Length= 00000014 Public STDCALL


Symbols:

                N a m e                 Type     Value    Attr

@CodeSize  . . . . . . . . . . .	Number	 00000000h   
@DataSize  . . . . . . . . . . .	Number	 00000000h   
@Interface . . . . . . . . . . .	Number	 00000003h   
@Model . . . . . . . . . . . . .	Number	 00000007h   
@code  . . . . . . . . . . . . .	Text   	 _TEXT
@data  . . . . . . . . . . . . .	Text   	 FLAT
@fardata?  . . . . . . . . . . .	Text   	 FLAT
@fardata . . . . . . . . . . . .	Text   	 FLAT
@stack . . . . . . . . . . . . .	Text   	 FLAT
sum  . . . . . . . . . . . . . .	DWord	 00000000 _DATA	

	   0 Warnings
	   0 Errors

主要看下以下三条:

 00000000  B8 00000005		    mov eax, 5
 00000005  83 C0 06		    add eax, 6
 00000008  A3 00000000 R	    mov sum, eax

B8 代表 mov ax, immed16;83 C0 猜测与 add 之类有关,这个得去查手册;A3 代表 mov [mem16], ax

AddVariables 程序

修改 AddVariables 程序使其使用 64 位变量。描述汇编器产生的语法错误,并说明为解决这些错误采取的措施。

.386
.model flat, stdcall
.stack 4096

ExitProcess PROTO, dwExitCode: DWORD

.data
firstval DWORD 20002000h
secondval DWORD 11111111h
thirdval DWORD 22222222h
sum DWORD 0

.code
main PROC
    mov rax, firstval
    add rax, secondval
    add rax, thirdval
    mov sum, rax

    INVOKE ExitProcess, 0
main ENDP
END main

报错:

undefined symbol : rax	

解决方法:

ExitProcess PROTO

.data
firstval QWORD 20002000h
secondval QWORD 11111111h
thirdval QWORD 22222222h
sum QWORD 0

.code
main PROC
    mov rax, firstval
    add rax, secondval
    add rax, thirdval
    mov sum, rax
    
    mov ecx, 0
    call ExitProcess
main ENDP
END
© 版权声明
THE END
喜欢就支持一下吧
点赞8赞赏 分享
评论 抢沙发

请登录后发表评论