Intel汇编语言程序设计(第7版)第七章编程练习题答案

1. 显示ASCII十进制数

include irvine32.inc
includelib irvine32.lib

.data
strNum BYTE "100123456789765"

.code

; EDX 偏移量
; ECX 数的长度
; EBX 小数点的偏移量

WriteScaled PROC USES edx ebx ecx 
L0:
	cmp ecx, ebx
	jnz @F
	mov al, '.'
	call WriteChar
@@:
	mov al, BYTE PTR [edx]
	call WriteChar

	inc edx
	loop L0
	ret

WriteScaled ENDP

start:
	mov edx, OFFSET strNum
	mov ecx, LENGTHOF strNum
	mov ebx, 3
	call WriteScaled

	call WaitMsg
	invoke ExitProcess, 0
end	start

2. 扩展减法过程

include irvine32.inc
includelib irvine32.lib

.data
Num0	BYTE 5, 4, 7, 5, 3, 7, 8, 9, 0, 5, 8, 3, 2, 5, 7, 9
Num1	BYTE 2, 2, 5, 8, 6, 8, 7, 3, 8, 9, 0, 5, 4, 2, 8, 2
Result	BYTE 64 DUP(0)
.code

Extended_Sub PROC pNum0:PTR BYTE, pNum1:PTR BYTE, dwLen:DWORD
	mov esi, pNum0
	mov edi, pNum1
	mov ecx, dwLen
	mov ebx, OFFSET Result
	add esi, ecx
	add edi, ecx
	dec esi 
	dec edi

	pushad
	; 清除CF标志位
	clc
L0:
	; 进行了减法, 可能产生了借位
	mov al, BYTE PTR [esi]
	sbb	al, BYTE PTR [edi]
	; 保存标志寄存器, 主要是CF
	pushfd
	; 如果存在借位则加1
	jnc @F
	add al, 10
@@:
	mov BYTE PTR [ebx + ecx - 1], al
	dec esi
	dec edi
	popfd
	loop L0
	popad

	ret
Extended_Sub ENDP

start:
	push LENGTHOF Num0
	push OFFSET Num1
	push OFFSET Num0
	call Extended_Sub

	call WaitMsg
	invoke ExitProcess, 0
end	start

3. 压缩十进制转换

include irvine32.inc
includelib irvine32.lib

.data
ddata		BYTE 5, 7, 2, 3
ascidata 	BYTE 4 DUP(0)
.code
PackedToAsc PROC CompressedDec:PTR BYTE, AsciiDec:PTR BYTE
	mov esi, CompressedDec
	mov ecx, 4
	mov edi, AsciiDec
L0:
	mov al, BYTE PTR [esi]
	xor BYTE PTR [edi], al
	xor BYTE PTR [edi], 30h
	inc esi
	inc edi
	loop L0
	ret
	
PackedToAsc ENDP

start:
	push OFFSET ascidata
	push OFFSET ddata
	call PackedToAsc

	mov ecx, 4
	mov edi, OFFSET ascidata
@@:
	mov al, BYTE PTR [edi]
	call WriteChar
	dec ecx
	inc edi
	test ecx, ecx
	jnz @B

	call WaitMsg
	invoke ExitProcess, 0
end	start

4. 用循环位移操作进行加密

include irvine32.inc
includelib irvine32.lib

.data
key		SBYTE -2, 4, 1, 0, -3, 5, 2, -4, -4, 6
asci	BYTE  "Hello, world! What do you want? Do you wanna have lunch with me and your treat Ooops..", 0
.code

EncOneByte PROC USES ebx bCh:BYTE, bKey:SBYTE
	mov al, bCh
	movzx ebx, bKey
	cmp bKey, 0
	jz Ending
	jl LeftShift
RightShift:
	ror al, 1
	dec bl
	test bl, bl
	jnz RightShift
	jmp Ending
LeftShift:
	rol al, 1
	inc bl
	test bl, bl
	jnz LeftShift
KeyZero:	
	mov al, bCh
Ending:
	ret

EncOneByte ENDP

DecOneByte PROC USES ebx bCh:BYTE, bKey:SBYTE
	mov al, bCh
	movzx ebx, bKey
	cmp bKey, 0
	jz Ending
	jl LeftShift
RightShift:
	rol al, 1
	dec bl
	test bl, bl
	jnz RightShift
	jmp Ending
LeftShift:
	ror al, 1
	inc bl
	test bl, bl
	jnz LeftShift
KeyZero:	
	mov al, bCh
Ending:
	ret

DecOneByte ENDP

ShiftEncrypt PROC pOrigin:PTR BYTE, BufLen:DWORD
	
	mov esi, pOrigin
	mov edi, OFFSET key
	mov ecx, BufLen
	mov ebx, LENGTHOF key
	xor edx, edx
L0:
	movzx eax, BYTE PTR [edi]
	push eax
	movzx eax, BYTE PTR [esi]
	push eax
	call EncOneByte
	mov BYTE PTR [esi], al
	inc esi
	inc edi
	inc edx
	cmp edx, LENGTHOF key
	jnz @F
	xor edx, edx
	sub edi, 10
@@:
	loop L0
	ret
ShiftEncrypt ENDP

ShiftDecrypt PROC pOrigin:PTR BYTE, BufLen:DWORD
	
	mov esi, pOrigin
	mov edi, OFFSET key
	mov ecx, BufLen
	mov ebx, LENGTHOF key
	xor edx, edx
L0:
	movzx eax, BYTE PTR [edi]
	push eax
	movzx eax, BYTE PTR [esi]
	push eax
	call DecOneByte
	mov BYTE PTR [esi], al
	inc esi
	inc edi
	inc edx
	cmp edx, LENGTHOF key
	jnz @F
	xor edx, edx
	sub edi, 10
@@:
	loop L0
	ret
ShiftDecrypt ENDP

start:
	; 原文打印
	mov edx, OFFSET asci
	mov ecx, LENGTHOF asci
	call WriteString
	call Crlf
	; 加密后打印
	push LENGTHOF asci - 1
	push OFFSET asci
	call ShiftEncrypt

	mov edx, OFFSET asci
	mov ecx, LENGTHOF asci
	call WriteString
	call Crlf
	; 解密后打印
	push LENGTHOF asci - 1
	push OFFSET asci
	call ShiftDecrypt

	mov edx, OFFSET asci
	mov ecx, LENGTHOF asci
	call WriteString
	call Crlf

	call WaitMsg
	invoke ExitProcess, 0
end	start

5. 素数

include windows.inc
include kernel32.inc
includelib kernel32.lib
include msvcrt.inc
includelib msvcrt.lib

.data
ARYNUM		= 1000
strPause	BYTE "pause", 0
dwNumAry	BYTE ARYNUM DUP(FALSE)
dwResAry	DWORD ARYNUM DUP(0)

strHasFalse	BYTE "有false", 0
strNoFalse  BYTE "没false", 0
.code

InitAry	PROC USES edi eax ecx pbAry:PTR BYTE, dwAryNum:DWORD
	mov ecx, dwAryNum
	mov edi, pbAry
	mov al, TRUE
	rep stosb
	ret

InitAry ENDP

SievePrime	PROC dwNum:DWORD, pAry:PTR DWORD
	LOCAL @Index:DWORD, @Inner:DWORD, @MaxNum:DWORD, @bPrimeAry[ARYNUM]:BYTE

	; 初始化prime数组
	push ARYNUM
	lea eax, @bPrimeAry
	push eax
	call InitAry

	; 判定是否小于2, 小于2代表没有数组
	mov @Index, 2
	mov eax, dwNum
	cmp eax, @Index
	jb  NoPrime
	; 获取需要检测的最大值
	mov @MaxNum, 31

L0:
	mov ecx, @Index
	push ecx

	; 求Index * Index, 保存到@Inner中
	mov ebx, @Index
	xor edx, edx
	mov eax, @Index
	mul ebx

	; 进行素数筛选
	mov @Inner, eax
L1:
	mov bl, TRUE
	cmp bl, [@bPrimeAry + eax]
	jne @F
	mov BYTE PTR [@bPrimeAry + eax], FALSE
@@:
	mov eax, @Inner
	add eax, eax 
	mov @Inner, eax
	cmp eax, ARYNUM
	jbe L1
	
	pop ecx
	mov ecx, @Index
	inc ecx
	mov @Index, ecx
	cmp ecx, @MaxNum
	jbe L0

NoPrime:
	xor eax, eax
Ending:
	ret 

SievePrime ENDP
end

6. 最大公约数(GCD)

GCD PROC x:SDWORD, y:SDWORD
	cmp x, 0
	jnl @F
	mov ebx, -1
	xor edx, edx
	mov eax, x
	mul ebx 
	mov x, eax 
@@:
	cmp y, 0
	jnl @F
	mov ebx, -1
	xor edx, edx
	mov eax, y
	mul ebx
	mov y, eax 
@@:
	mov eax, x
	xor edx, edx
	mov ebx, y
	div ebx 
	mov x, ebx
	mov y, edx 
	cmp edx, 0
	ja @B
	mov eax, x
	ret

GCD ENDP

7. 位元乘法

includelib kernel32.lib
includelib user32.lib
include irvine32.inc
includelib irvine32.lib

ExitProcess PROTO STDCALL, uExitCode:DWORD

.data
strPause	BYTE "pause", 0
.code

BitwiseMultiply PROC
	LOCAL @dwMultiplier:DWORD
	
	mov ecx, 20h
	mov @dwMultiplier, eax
	xor eax, eax  
	mov edx, -1 
L1:
	ror ebx, 1
	inc edx
	dec ecx  
	jc @F 
	test ecx, ecx 
	jnz L1 
	jmp Ending
@@:
	mov esi, @dwMultiplier
	push ecx 
	mov ecx, edx  
	shl esi, cl 
	pop ecx 
	add eax, esi 
	jmp L1
Ending:
	ret 

BitwiseMultiply	ENDP 

main PROC
	mov eax, 21	
	mov ebx, 43 
	call BitwiseMultiply
	call WriteDec
Ending:
	call WaitMsg
	invoke ExitProcess, 0
main ENDP
end	main

8. 压缩整数乘法

includelib kernel32.lib
includelib user32.lib
include irvine32.inc
includelib irvine32.lib

ExitProcess PROTO STDCALL, uExitCode:DWORD

.data
strPause	BYTE "pause", 0
NUMBITS	= 4
RESULTBITS	= (NUMBITS + 1)

bNum1Ary	BYTE 5, 3, 2, 9
bNum2Ary	BYTE 7, 4, 1, 3
bResultAry	BYTE RESULTBITS DUP(0)

.code

AddPacked PROC 
	add esi, ecx 
	dec esi 
	add edi, ecx 
	dec edi 
	add edx, ecx  
	; 设置DF反向
	std 
L0:
	lodsb 
	add al, BYTE PTR [edi]
	cmp al, 0Ah 
	jb @F
	sub al, 0Ah 
	; 进位
	add BYTE PTR [edx - 1], 1
@@:
	add BYTE PTR [edx], al 
	dec edx
	dec edi 
	loop L0

	ret 
AddPacked ENDP 

main PROC
	mov esi, OFFSET bNum1Ary
	mov edi, OFFSET bNum2Ary
	mov ecx, NUMBITS 
	mov edx, OFFSET bResultAry
	call AddPacked

	mov ecx, RESULTBITS
	mov edx, OFFSET bResultAry
	xor eax, eax
	xor esi, esi 
L0:
	mov al, BYTE PTR [bResultAry + esi]
	call WriteDec
	inc esi
	loop L0
Ending:
	call WaitMsg
	invoke ExitProcess, 0
main ENDP
end	main

(完)

你可能感兴趣的:(IA-32,x32控制台汇编,assembly,汇编)