Kip Irvine 汇编语言 基于x86处理器 Chapter04 代码(含习题)

案例代码

01.寄存器 值的覆盖


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	oneByte		byte	78h
	oneWord		word	1234h
	oneDword	dword	12345678h
	
.code
	main PROC
		
		mov eax,0
		mov al,oneByte
		mov ax,oneWord
		mov eax,oneDword

		mov ax,0

		invoke ExitProcess,0
	main ENDP
END main

02.无符号扩展指令 movzx


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	byteVal		BYTE		1000111b

.code
	main PROC
		;进行无符号扩展
		movzx ax,byteVal

		;0扩展
		mov bx,0A69Bh
		movzx eax,bx
		movzx edx,bl
		movzx cx,bl

		invoke ExitProcess,0
	main ENDP
END main

03.有符号扩展指令 movsx


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	byteVal1		byte	1000111b
	byteVal2		byte	10001111b
.code
	main PROC
		movsx	ax,byteVal1
		movsx	bx,byteVal2

		;立即数和寄存器之间的扩展
		mov		bx,0A69Bh
		movsx	eax,bx
		movsx	edx,bl
		movsx	cx,bl

		invoke ExitProcess,0
	main ENDP
END main

04.LAHF 加载状态标志位到AH


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	saveFlags	byte	?

.code
	main PROC
		lahf					;将标志位加载到ah
		mov saveFlags,ah		;用变量保存这些标志位

		invoke ExitProcess,0
	main ENDP
END main

05.SAHF 将AH中的内容复制到EFLAGS


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	saveflags	byte  11111111b 
.code
	main PROC

		mov ah,saveflags
		SAHF			;将状态字寄存器更新

		invoke ExitProcess,0
	main ENDP
END main

06.XCHG指令


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	var1  word  100
	var2  word  200

.code
	main PROC
		;对寄存器的操作
		mov ax,1
		mov bx,2
		xchg ax,bx

		;对内存地址的操作 需要借助寄存器
		mov ax,var1
		xchg ax,var2
		mov var1,ax

		invoke ExitProcess,0
	main ENDP
END main

07.直接-偏移量操作数


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	arrayB	BYTE	10h,20h,30h,40h,50h	;定义一个字节数组

.code
	main PROC
		
		;使用直接-偏移量操作数组        ;数组名可以指代第一个元素
		mov al,[arrayB+1]				;访问元素20h
		mov al,[arrayB+2]				;访问元素30h
		;括号相当于C语言中的&,意思就是区的地址中的元素的值
		;与C语言相通,这里的下标不可以越界
		invoke ExitProcess,0
	main ENDP
END main

08.使用直接偏移量操作数操作字数组与双字数组


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	arrayW	WORD	100h,200h,300h
	arrayD	DWORD	10000h,20000h

.code
	main PROC
		;对word数组进行操作
		mov ax,arrayW
		mov ax,[arrayW+2]		;+2的目的是为了取得WORD数组中的下一个元素 每加一一次指针前进一个byte

		;对DWORD数组进行操作
		mov eax,arrayD
		mov eax,[arrayD+4]		;+4的目的是为了取得DWORD数组中的下一个元素 每加一一次指针前进一个byte

		invoke ExitProcess,0
	main ENDP
END main

09.Moves示例程序


;数据传送实例	(Moves.asm)
.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	val1	WORD	1000h
	val2	WORD	2000h
	arrayB	BYTE	10h,20h,30h,40h,50h
	arrayW	WORD	100h,200h,300h
	arrayD	DWORD	10000h,20000h

.code
	main PROC

		;演示MOVZX指令
		mov	bx,0A69Bh			;bx=0A69Bh
		movzx	eax,bx			;EAX=0000A69Bh
		movzx	edx,bl			;EDX=0000009Bh
		movzx	cx,bl			;CX=009Bh

		;演示MOVSX指令
		mov bx,0A69Bh			;bx=0A69Bh
		movsx	eax,bx			;EAX=FFFFA69Bh
		movsx	edx,bl			;EDX=FFFFFF9Bh
		mov		bl,7Bh			;BL=7Bh
		movsx	cx,bl			;CX=007Bh  最高位小于等于7所以扩展以后高位补0

		;演示内存-内存的交换
		mov		ax,val1			;AX=1000h
		xchg	ax,val2			;AX=2000h	val2=1000h
		mov		val1,ax			;val1=2000h

		;演示直接-偏移寻址(字节数组)
		mov		al,[arrayB]		;AL=10h
		mov		al,[arrayB+1]	;AL=20h
		mov		al,[arrayB+2]	;AL=30h

		;演示直接偏移量寻址(字数组)
		mov		ax,[arrayW]		;AX=100h
		mov		ax,[arrayW+2]	;AX=200h

		;演示直接偏移量寻址(双字数组)
		mov		eax,arrayD		;EAX=10000h
		mov		eax,[arrayD+4]	;EAX=20000h

		invoke ExitProcess,0
	main ENDP
END main

10.inc指令


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	myWord	WORD	1000h

.code
	main PROC
		inc myWord		;inc指令直接可以操作内存元素以及寄存器

		invoke ExitProcess,0
	main ENDP
END main

11.dec指令


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	myWord	WORD 100h
	
.code
	main PROC
		dec myWord

		invoke ExitProcess,0
	main ENDP
END main

12.add


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	var1	DWORD	10000h
	var2	DWORD	20000h

.code
	main PROC

		mov eax,var1
		add eax,var2

		invoke ExitProcess,0
	main ENDP
END main

13.sub


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	var1	DWORD	30000h
	var2	DWORD	10000h

.code
	main PROC
		
		mov	eax,var1	;EAX=30000
		sub eax,var2	;EAX=20000

		invoke ExitProcess,0
	main ENDP
END main

14.NEG指令


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC
		mov eax,11111h
		NEG	eax				;neg指令的本质是求补运算

		invoke ExitProcess,0
	main ENDP
END main

15.执行算术表达式的例子


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	Rval	SDWORD	?
	Xval	SDWORD	26
	Yval	SDWORD	30
	Zval	SDWORD	40

.code
	main PROC
		
		;first term -Xval
		mov eax,Xval		;EAX=26
		neg	eax				;EAX=-26

		;second term (Yval-Zval)
		mov ebx,Yval
		sub ebx,Zval		;EBX=-10

		;add the terms and store
		add eax,ebx			;-36
		mov Rval,eax

		invoke ExitProcess,0
	main ENDP
END main

16.AddSubTest


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	Rval	SDWORD	?
	XVal	SDWORD	26
	YVal	SDWORD	30
	ZVal	SDWORD	40

.code
	main PROC
		
		;INC和DEC
		mov	ax,1000h
		inc ax			;1001h
		dec ax			;1000h

		;表达式 Rval=-Xval+(Yval-Zval)
		mov eax,Xval
		neg	eax			;-26	neg指令用来将一个数字取反加一 相当于求解这个数的相反数
		mov ebx,Yval	
		sub ebx,Zval	;-10
		add eax,ebx		
		mov Rval,eax	;-36

		;零标志位实例
		mov cx,1
		sub cx,1		;ZF=1
		mov ax,0ffffh	
		inc ax   		;ZF=1

		;符号标志位实例
		mov cx,0
		sub cx,1		;SF=1
		mov ax,0ffh		
		add ax,2		;SF=1

		;进位标志位实例
		mov al,0ffh		
		add al,1		;CF=1,AL=00h

		;溢出标志位实例
		mov al,+127		;AL=1111 1111
		add al,1		;OF=1
		mov al,-128
		sub al,1		;OF=1



		invoke ExitProcess,0
	main ENDP
END main

17.OFFSET运算符


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	bVal	BYTE	?
	wVal	WORD	?
	dVal	DWORD	?
	dVal2	DWORD	?

.code
	main PROC
								;一种可能的内存地址分布情况
		mov esi,OFFSET bVal		;esi=0x00654000
		mov esi,OFFSET wVal		;esi=0x00654001
		mov esi,OFFSET dVal		;esi=0x00654003
		mov esi,OFFSET dVal2	;esi=0x00654007

		invoke ExitProcess,0
	main ENDP
END main

18.offset在直接-偏移量操作数上的应用


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	myArray		DWORD		1,2,3,4,5

.code
	main PROC
		
		mov esi,myArray+4	;esi的值为2  4指的是字节数


		invoke ExitProcess,0
	main ENDP
END main

19.使用一个双字变量初始化另外一个双字变量充当指针


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	bigArray	DWORD	500 DUP(0)	;生成一个连续的数组 这个数组的大小为500 初始值全部为0
	pArray		DWORD	bigArray	;注意pArray里面保存的实际上是bigArray的内存地址

.code
	main PROC

		mov esi,pArray				;直接将bigArray的首地址赋值给esi寄存器
		invoke ExitProcess,0
	main ENDP
END main

20.ALIGN伪指令对其字节边界


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data												;一种可能的地址分布
	bVal	BYTE	?								;0x00AD4000
	ALIGN	2			;下一个变量的地址为2的倍数
	wVal	WORD	?								;0x00AD4002
	bVal2	BYTE	?								;0x00AD4004
	ALIGN	4			;下一个变量的地址为4的倍数
	dVal	DWORD	?								;0x00AD4008
	dVal2	DWORD	?								;0x00AD400C

.code
	main PROC


		invoke ExitProcess,0
	main ENDP
END main

21.PTR运算符


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data 
	myDouble	DWORD	12345678h

.code
	main PROC
		
		;mov ax,myDouble			;错误操作 instruction operands must be the same size
		mov ax,word ptr myDouble	;位数不匹配的时候如果是将大字节赋值给小字节那么小字节被赋予的值是大字节的低位
									;ax=5678h
		;如果需要获得该变量的其他位置的字那么就需要手动修改ptr所指向的位置
		mov ax,word ptr [myDouble+2];ax=1234h

		invoke ExitProcess,0
	main ENDP
END main

22.将较小的值送入较大的值中


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	wordList	WORD	5678h,1234h
.code
	main PROC

		mov eax,DWORD ptr wordList	;按相对于DWORD的小端方式组合 结果是12345678h

		invoke ExitProcess,0
	main ENDP
END main

23.TYPE运算符


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	var1	BYTE	?
	var2	WORD	?
	var3	DWORD	?
	var4	QWORD	?

.code
	main PROC
		;TYPE运算符返回变量单个元素的大小 单位是字节

		mov eax,TYPE var1
		mov eax,TYPE var2
		mov eax,TYPE var3
		mov eax,TYPE var4

		invoke ExitProcess,0
	main ENDP
END main

24.LENGTHOF运算符


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	;LENGTHOF运算符计算一个数组里面的数组元素个数
	byte1		BYTE	10,20,30,40
	array1		WORD	30 DUP(?),0,0	;定义了一个32个WORD大小的数组
	array2		WORD	5 DUP(3 DUP(?))	;定义了一个5X3的二维数组
	array3		DWORD	1,2,3,4
	digitStr	BYTE	"12345678",0	;字符串的长度是8byte 字符串的结尾标志有一个0

.code
	main PROC
		mov eax,LENGTHOF byte1
		mov eax,LENGTHOF array1
		mov eax,LENGTHOF array2
		mov eax,LENGTHOF array3
		mov eax,LENGTHOF digitStr

		invoke ExitProcess,0
	main ENDP
END main

25.LENGTHOF运算符在多行定义的数组中的使用


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	myArray	BYTE	10,20,30,40,50,	;如果需要换行编写,那么就需要在换行的位置加上,
					60,70,80,90,00

.code
	main PROC
		
		mov eax,LENGTHOF myArray

		invoke ExitProcess,0
	main ENDP
END main

26.SIZEOF运算符


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	;SIZEOF运算符的大小是LENGTHOF*TYPE
	intArray	WORD	32 DUP(0)

.code
	main PROC
		mov eax,SIZEOF intArray	;EAX中的内容是 2*32=64 

		invoke ExitProcess,0
	main ENDP
END main

27.LABEL伪指令


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	val16	LABEL	WORD		;LABEL仅仅是说明val16存在于val32之前但是并没有为它分配地址空间
	val32	DWORD	12345678h

	longValue	LABEL	DWORD	;LABEL有的时候也可以用来组合内存中的数据
	value1		WORD	5678h
	value2		WORD	1234h	;这个时候longValue指代的数据就是12345678h

.code
	main PROC

		mov ax,val16			;ax=5678h
		mov dx,[val16+2]		;dx=1234h

		mov eax,longValue		;EAX=12345678h
		invoke ExitProcess,0
	main ENDP
END main

28.步进遍历数组


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	arrayB	BYTE	10h,20h,30h,40h
	arrayW	WORD	1000h,2000h,3000h

.code
	main PROC

		mov esi,OFFSET arrayB
		mov al,[esi]			;AL=10
		inc esi					;esi增加一个字节
		mov al,[esi]			;AL=20
		inc esi					;esi增加一个字节
		mov al,[esi]			;AL=30
		inc esi					;esi增加一个字节
		mov al,[esi]			;AL=40
		inc esi					;esi增加一个字节


		mov esi,OFFSET arrayW
		mov ax,[esi]			;AL=1000
		add esi,2				;esi增加两个字节
		mov ax,[esi]			;AL=2000
		add esi,2				;esi增加两个字节
		mov ax,[esi]			;AL=3000
		add esi,2				;esi增加两个字节

		invoke ExitProcess,0
	main ENDP
END main

29.32bit整数相加


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	arrayD	DWORD	10000h,20000h,30000h

.code
	main PROC
		mov esi,OFFSET arrayD
		mov eax,[esi]		;第一个数
		add esi,4
		add eax,[esi]		;第二个数
		add esi,4
		add eax,[esi]		;第三个数

		invoke ExitProcess,0
	main ENDP
END main

30 变址操作数


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	arrayB	BYTE	10h,20h,30h
	arrayW	WORD	1000h,2000h,3000h
	arrayD	DWORD	100h,200h,300h,400h
	arrayE	DWORD	1,2,3,4

.code
	main PROC
		
		mov esi,0
		mov al,arrayB[esi]		;AL=10h	这里实际上就相当于C语言中的数组 arrayB表示的就是数组的首地址

		mov	esi,OFFSET arrayW
		mov ax,[esi]			;AX=1000h
		mov ax,[esi+2]			;AX=2000h	WORD一共有两个字节
		mov ax,[esi+4]			;AX=3000h	WORD一共有两个字节

		;使用十六位寄存器 SI DI BX BP
		;;变址操作数中的比例因子
		mov esi,OFFSET arrayD
		add esi,3*TYPE arrayD	;400h的偏移量
		mov eax,[esi]			;注意这里不要写成arrayD[esi]



		invoke ExitProcess,0
	main ENDP
END main

31.变址操作中的比例因子


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	arrayD	DWORD	100h,200h,300h,400h


.code
	main PROC

		mov esi,3
		mov eax,arrayD[esi*4]			;4是arrayD里面每一个元素所占的字节数

		mov esi,3
		mov eax,arrayD[esi*TYPE arrayD]	;eax最终的值是400h

		invoke ExitProcess,0
	main ENDP
END main

32.pointers程序 PTR 与 TYPEDEF 的运用


.386p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


	;创建用户自定义数据类型
	PBYTE	TYPEDEF	PTR	BYTE	;定义字节指针
	PWORD	TYPEDEF PTR	WORD	;定义字指针
	PDWORD	TYPEDEF PTR	DWORD	;定义双字指针

.data
	
	arrayB	BYTE	10h,20h,30h
	arrayW	WORD	1,2,3
	arrayD	DWORD	4,5,6

	;创建指针变量
	ptr1	PBYTE	arrayB
	ptr2	PWORD	arrayW
	ptr3	PDWORD	arrayD

.code
	main PROC

		;使用指针访问数据
		mov esi,ptr1
		mov al,[esi+0]		;al=10h

		mov esi,ptr2
		mov ax,[esi+0]		;ax=1

		mov esi,ptr3
		mov eax,[esi+0]		;eax=4

		invoke ExitProcess,0
	main ENDP
END main

33.数组求和程序


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	intarray	DWORD	10000h,20000h,30000h,40000h

.code
	main PROC
		
		mov edi,OFFSET intarray		;EDI=intarray地址
		mov ecx,LENGTHOF intarray	;循环计数器初始化
		mov eax,0					;sum=0

	L1:
		add eax,[edi]				;加一个整数
		add edi,TYPE intarray		;指向下一个元素  TYPE返回一个数组内部单个元素的大小
		loop L1						;重复,直到ECX=0			

		invoke ExitProcess,0
	main ENDP
END main

34.字符串复制程序


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	;TYPE运算符返回变量单个元素的大小 单位是字节
	;LENGTHOF运算符计算一个数组里面的数组元素个数
	;SIZEOF运算符的大小是LENGTHOF*TYPE
	
	source	BYTE	"This is the source string",0
	target	BYTE	SIZEOF source dup(0)		;初始化存储空间

.code
	main PROC
		mov esi,0				;变址寄存器
		mov ecx,SIZEOF source	;循环计数器
	L1:
		;一个字节一个字节的进行复制
		mov al,source[esi]		;从原字符串中获取一个字符
		mov target[esi],al		;保存到目标字符串
		inc esi					;重复,直到整个字符串完成
		loop L1

		invoke ExitProcess,0
	main ENDP
	END main

习题

4.2.8 01-05


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	val1 BYTE 10h
	val2 WORD 8000h
	val3 DWORD 0ffffh
	val4 WORD 7fffh

.code
	main PROC
		
		;1
		inc val2
		;2
		sub eax,val3
		;3
		mov bx,val4
		sub val2,bx
		;4
		add val2,1
		;5
		add val4,1

		invoke ExitProcess,0
	main ENDP
END main

4.5.5 05-06


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	myBytes		BYTE	10h,20h,30h,40h
	myWords		WORD	8Ah,3Bh,72h,44h,66h
	myDoubles	DWORD	1,2,3,4,5
	myPointer	DWORD	myDoubles

.code
	main PROC
									;一种可能并且合理的结果
		;05
		mov esi,OFFSET myBytes		;ESI=0x00554000
		mov al,[esi]				;AL=0x10
		mov al,[esi+3]				;AL=0x40

		mov esi,OFFSET myWords+2	;ESI=0x554006
		mov ax,[esi]				;AX=0x003Bh
		
		mov edi,8					;EDI=8
		mov edx,[myDoubles+edi]		;EDX=3
		mov edx,myDoubles[edi]		;EDI=3

		mov ebx,myPointer			;EBX=0x0055400e
		mov eax,[ebx+4]				;EAX=2

		;06
		mov esi,OFFSET myBytes		;ESI=0x00554000
		mov ax,[esi]				;AX=10
		mov eax,DWORD PTR myWords	;eax=0x003b008a
		mov esi,myPointer			;ESI=0x0055400e
		mov ax,[esi+2]				;AX=0
		mov ax,[esi+6]				;AX=0
		mov ax,[esi-4]				;AX=44h


		invoke ExitProcess,0
	main ENDP
END main

4.9.1


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	dVal	DWORD	?

	var1	SBYTE	-4,-2,3,1
	var2	WORD	1000h,2000h,3000h,4000h
	var3	SWORD	-16,-42
	var4	DWORD	1,2,3,4,5
	 
.code
	main PROC
		;05
		;mov al,1
		;add al,3

		;11
		;mov dVal,12345678h
		;mov ax,WORD ptr dVal+2
		;add ax,3
		;mov WORD ptr dVal,ax
		;mov eax,dVal

		;16~19

		;mov ax,var1					;类型不匹配
		;mov ax,var2					;类型不匹配
		;mov eax,var3					;类型不匹配
		;mov var2,var3					;非法指令
		;movzx ax,var2					;var2是有符号数 指令非法
		;movzx var2,al					;var2是有符号数 指令非法
		;mov ds,ax						;保护模式下 发生异常
		;mov ds,1000h					;ds寄存器的赋值操作不支持立即数


		;mov al,var1					;0xfc
		;mov ah,[var1+3]				;0x01


		;mov ax,var2					;1000
		;mov ax,[var2+4]				;3000
		;mov ax,var3					;0xfff0h
		;mov ax,[var3-2]				;4000


		mov edx,var4					;0x00000001
		movzx edx,var2					;0x00001000
		mov	edx,[var4+4]				;0x00000002
		movsx edx,var1					;0xFFFFFFFC	实际上就是求解-4的补码fffc之后在进行高位扩展

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 01


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	three	DWORD	11112222h

.code
	main PROC
		mov ax,word ptr three
		mov bx,word ptr [three+2]

		mov word ptr [three+2],ax
		mov word ptr three,bx
		invoke ExitProcess,0
	main ENDP
END main

4.9.2 02


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC
		
		mov al,1
		mov bl,2
		mov cl,3
		mov dl,4

		xchg	bl,al
		xchg	al,cl
		xchg	al,dl
		xchg	al,cl
		xchg	bl,dl

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 04


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC

		
		mov al,-127
		mov bl,-2
		add al,bl

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 05


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC
		

		mov al,255
		sub al,2
		add al,3

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 06


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC
		
		mov al,0
		sub al,1

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 07


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	val1	DWORD	1
	val2	DWORD	2
	val3	DWORD	3

.code
	main PROC

		mov eax,7
		sub eax,val2
		sub eax,val3
		add eax,val1
		invoke ExitProcess,0
	main ENDP
END main

4.9.2 08


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array	DWORD	1,2,3,4
	sum		DWORD	0

.code
	main PROC
		
		mov ecx,LENGTHOF array
		mov eax,0
		mov esi,0

		L:
			add eax,array[esi*TYPE array]
			inc esi
			loop L

		mov sum,eax
		invoke ExitProcess,0
	main ENDP
	END main

4.9.2 09


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	val2	WORD	1
	val4	WORD	2
	res		WORD	0
.code
	main PROC
		mov bx,3
		add bx,val2
		sub bx,val4
		mov ax,val2
		mov res,ax

		invoke ExitProcess,0
	main ENDP
END main

4.9.2 10


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC

		mov al,127
		add al,2
		invoke ExitProcess,0
	main ENDP
END main

4.9.2 12-16


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	myBytes		BYTE	10h,20h,30h,40h
	ALIGN 2
	myWords		WORD	4000h,3000h,2000h
	myString	BYTE	"ABCDE"

.code
	main PROC
		;;13
		;mov eax,TYPE myBytes		;1
		;mov eax,LENGTHOF myBytes	;4
		;mov eax,sizeof myBytes		;4

		;mov eax,TYPE myWords		;2
		;mov eax,LENGTHOF myWords	;4
		;mov eax,sizeof myWords		;8

		;mov eax,sizeof myString	;5

		;;14
		;mov dx,word ptr myBytes
		
		;;15
		;mov al,byte ptr [myWords+1]	;这里获得的是按照小端方式的内存中的第二个字节

		;;16
		;mov eax,dword ptr [myBytes]

		invoke ExitProcess,0
	main ENDP
	END main

4.9.2 17-18


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	words		LABEL	DWORD
	myBytes		BYTE	10h,20h,30h,40h
	myWords		WORD	4000h,3000h,2000h
	myString	BYTE	"ABCDE"

.code
	main PROC
		
		mov eax,words
		invoke ExitProcess,0
	main ENDP
END main

4.10 01


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	bigEndian		BYTE	12h,34h,56h,78h
	littleEndian	DWORD	?

.code
	main PROC
		
		mov al,byte ptr [bigEndian+0]
		mov ah,byte ptr [bigEndian+1]
		mov bl,byte ptr [bigEndian+2]
		mov bh,byte ptr [bigEndian+3]

		mov byte ptr [littleEndian+3],al
		mov byte ptr [littleEndian+2],ah
		mov byte ptr [littleEndian+1],bl
		mov byte ptr [littleEndian+0],bh

		invoke ExitProcess,0
	main ENDP
END main

4.10 02


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	arr	BYTE	1,2,3,4,5,6,7,8

.code
	main PROC
		;首先计算arr数组长度的一半
		mov ecx,lengthof arr
		mov eax,ecx
		mov bl,2
		div bl
		mov ecx,eax
		;设置偏移地址寄存器
		mov edi,0

		L:
			mov al,arr[edi]
			mov ah,arr[edi+1]
			mov arr[edi],ah
			mov arr[edi+1],al

			add edi,2

			loop L


		invoke ExitProcess,0
	main ENDP
END main

4.10 03


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	arr		DWORD	0,2,5,9,10
	sum		DWORD	0
.code
	main PROC
		
		mov esi,OFFSET arr
		mov ecx,lengthof arr-1
		mov eax,0
	L:
		add eax,[esi+4]
		sub eax,[esi]
		add esi,4
		loop L

		invoke ExitProcess,0
	main ENDP
END main

4.10 04


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	unsingedWordArray	WORD	1,2,3,4,5
	unsingedDWordArray	DWORD	5 DUP(0)
.code
	main PROC
		mov ecx ,Lengthof unsingedDWordArray
		mov edi,0
		L:
			;ax依次获取到unsingedWordArray数组中的元素
			mov ax,word ptr [unsingedWordArray+edi]
			add edi,2
			
			;将ax中的内容扩展到DWORD然后复制到unsingedDWordArray中
			movzx ebx,ax
			mov dword ptr [unsingedDWordArray+edi+edi],ebx

			loop L



		invoke ExitProcess,0
	main ENDP
END main

4.10 05


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	sum	dword 0
.code
	main PROC
		mov eax,1
		mov ebx,1
		mov ecx,7
		l:
			add sum,eax
			mov edx,ebx
			add ebx,eax
			mov eax,edx

			loop l


		invoke ExitProcess,0
	main ENDP
	END main

4.10 06


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	;TYPE运算符返回变量单个元素的大小 单位是字节
	;LENGTHOF运算符计算一个数组里面的数组元素个数
	;SIZEOF运算符的大小是LENGTHOF*TYPE

	arr		byte	1,2,3,4,5,6,7,8,9,10

.code
	main PROC
		
		;思路 使用栈
		mov esi,0
		mov ecx,lengthof arr
		L:
			movzx eax,arr[esi]
			inc esi
			push eax
			loop L
	
		mov esi,0
		mov ecx,lengthof arr
		U:
			pop eax
			mov arr[esi],al
			inc esi

			loop U
		


		invoke ExitProcess,0
	main ENDP
	END main

4.10 07

;字符串翻转		(RevStr.asm)
.386

.model flat,stdcall

.stack 4096

ExitProcess PROTO,dwExitCode:DWORD

.data
	aName BYTE "Abraham Lincoln",0
	nameSize=($-aName)-1

.code
	main PROC
		;将名字压入栈
		mov ecx,nameSize		;在这里值得注意的是,这里借助eax的原因,因为aName[esi]是八位变址操作数,但是
		mov esi,0				;32bit汇编语言里面栈的大小是32bit的,也就是说一个栈空间可以存储320,1二进制

	L1:
		movzx eax,aName[esi]	;获取字符 32bit零扩展传送 对齐内存
		push eax				;压入堆栈  压入堆栈制后只需要在取出的时候仅仅取到最低的八位就可以得到字符串每一位的
		inc esi					;ASCII码值,这里实际上是借助了大内存存储小内容得理念,其目的是便于操作对齐内存
		loop L1

		;将每一个栈中的32bit逆序弹出堆栈,并存入aName数组
		mov ecx,nameSize
		mov esi,0
	L2:
		pop eax					;获取字符
		mov aName[esi],al		;存入字符串
		inc esi

		loop L2

	invoke exitprocess,0
main endp
end main

4.10 08


.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	arr		DWORD	1,2,3,4,5,6,7,8
	tmp		DWORD	9 dup(0)
	len		DWORD	lengthof arr
.code
	main PROC
		;将arr复制到tmp
		mov ecx,len
		mov edi,0
		L:
			mov eax,arr[edi]
			mov tmp[edi+4],eax
			add edi,4
			loop L
		;将最后一个元素放到tmp的第一个位置
		mov edi,lengthof arr-1
		mov eax,[arr+edi*4]
		mov tmp[0],eax
		
		;将tmp拷贝回arr
		mov ecx,len
		mov edi,0
		R:
			mov eax,[tmp+edi*4]
			mov [arr+edi*4],eax
			inc edi
			loop R

		invoke ExitProcess,0
	main ENDP
END main
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值