• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    (完)

  • 相关阅读:
    并行多核体系结构基础知识
    工业web4.0UI风格超凡脱俗
    大数据精品栏目介绍
    多线程使用
    centos docker服务问题
    MySQL - Heap 表是什么?
    基于C语言实现的Linux系统中的EXT2文件系统
    PAT 1174 Left-View of Binary Tree 题干不知所云
    SpringFramework:Spring AOP
    [递归]有理数树
  • 原文地址:https://blog.csdn.net/qq_37232329/article/details/133246234