Skip to content

Latest commit

 

History

History
1471 lines (1076 loc) · 25 KB

汇编语言-基于x86处理器-练习.md

File metadata and controls

1471 lines (1076 loc) · 25 KB
tags
language
汇编

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

includelib D:\masm32\lib\kernel32.lib
includelib D:\masm32\lib\User32.lib
includelib G:\[WORK]\ASM\Irvine\Irvine32.lib
include G:\[WORK]\ASM\Irvine\Irvine32.inc

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword


;7.9.2.7
COUNT = 4				; shift count

.data
;array DWORD 648B2165h,8C943A29h,6DFA4B86h,91F76C04h,8BAF9857h
array BYTE 81h, 20h, 33h

.code
main PROC

	mov  bl,COUNT
	call ShiftOp

; Display the results
	mov  esi,OFFSET array
	mov  ecx,LENGTHOF array
	mov  ebx,TYPE array
	call DumpMem

	exit
main ENDP

;---------------------------------------------------------------
ShiftOp PROC
; Shifts an array of doublewords to the right.
; The array is a global variable.
; Receives: BL = number of bits to shift
; Returns: nothing
;---------------------------------------------------------------
;	mov  esi,OFFSET array
;	mov  ecx,(LENGTHOF array) - 1
;
;L1:	push ecx				; save loop counter
;	mov  eax,[esi + TYPE DWORD]
;	mov  cl,bl				; shift count
;	shrd [esi],eax,cl			; shift EAX into high bits of [esi]
;	add  esi,TYPE DWORD			; point to next doubleword pair
;	pop  ecx					; restore loop counter
;	loop L1
;
;; Right-shift the last doubleword
;	shr DWORD PTR [esi],COUNT
;
;	ret


;原书的移动实际上是从array最末尾移动,改成从首端移动

;	mov  esi, OFFSET array + TYPE DWORD * ((LENGTHOF array) - 1)
;	mov  ecx,(LENGTHOF array) - 1
;
;L1:	push ecx				; save loop counter
;	mov  eax,[esi - TYPE DWORD]
;	mov  cl,bl				; shift count
;	shrd [esi],eax,cl			; shift EAX into high bits of [esi]
;	sub  esi,TYPE DWORD			; point to next doubleword pair
;	pop  ecx					; restore loop counter
;	loop L1
;
;; Right-shift the last doubleword
;	shr DWORD PTR [esi],COUNT
;
;	ret
;ShiftOp ENDP
	mov  esi, OFFSET array + TYPE BYTE * ((LENGTHOF array) - 1)
	mov  ecx,(LENGTHOF array) - 1

L1:	push ecx				; save loop counter
	mov eax, 0
	mov  al, [esi - TYPE BYTE]
	mov  cl,bl				; shift count

	movzx edx, BYTE PTR[esi]
	shrd dx,ax,cl
	or dl, dh			
	mov BYTE PTR[esi], dl
	
	sub  esi,TYPE BYTE			; point to next doubleword pair
	pop  ecx					; restore loop counter
	loop L1

; Right-shift the last doubleword
	shr BYTE PTR [esi],COUNT

	ret
ShiftOp ENDP

END main

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.

Exercise 8

1-找数组最大值

image-20220608115434816

include Irvine32.inc

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
FindLargest proto aPtr:PTR SDWORD, arraySize:DWORD

.data
	Ex1Array sdword 10,-20,30,50,40,-2 ; 50
	Ex1Array1 sdword 10,-20,30,50,40,-2,85 ; 85


.code

main PROC
   ;push OFFSET nums
   ;push LENGTHOF nums
   ;call  FindLargest


	invoke FindLargest, ADDR Ex1Array, LENGTHOF Ex1Array
	invoke FindLargest, ADDR Ex1Array1, LENGTHOF Ex1Array
	invoke ExitProcess,0
main ENDP

FindLargest PROC,
	aPtr:PTR SDWORD, arraySize:DWORD
  mov ecx, arraySize-1
  mov esi, aPtr
  L1:
    mov edx, [esi]
    cmp edx, [esi+TYPE DWORD]
	jl _next
	mov edx, [esi+TYPE DWORD]
	_next:
	add esi, TYPE DWORD
  LOOP L1

  mov eax, edx
  call WriteDec

  ret
FindLargest endp


;esi 数组地址,ecx 个数
showArray proc
 mov edx, 0;累加计数
L1:
  movzx eax, BYTE PTR [esi + TYPE BYTE *edx]
  call WriteDec
  ;mov eax, 0ah
  ;call WriteChar
  inc edx

  LOOP L1

  ret
showArray endp


END main

2-连续三个相同

image-20220608115515399

include Irvine32.inc

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
FindThrees proto p:PTR DWORD, n:DWORD

.data
	Ex1Array sdword 3,3,4,4,3,3,3,3,3,3,1 ; 50
	Ex1Array1 sdword 10,-20,30,50,40,-2,85 ; 85


.code

main PROC
   ;push OFFSET nums
   ;push LENGTHOF nums
   ;call  FindLargest


	invoke FindThrees, ADDR Ex1Array, LENGTHOF Ex1Array
	call WriteDec
	call Crlf
	invoke FindThrees, ADDR Ex1Array1,  Ex1Array
	call WriteDec
	call Crlf
	invoke ExitProcess,0
main ENDP

FindThrees proc p:PTR DWORD, n:DWORD
	push ebx
	push ecx
	push edx
	push esi
	push edi
	mov eax, 0

	mov edx, n
	mov ecx,3
	; 如果长度小于3就直接返回0
	cmp edx, ecx
	jl return

	mov esi, p

	lp3:			; 循环3次判断是不是连续的3
		mov ebx, [esi]			; 得到值

		add esi, TYPE DWORD		; 指针指向下一个
		sub edx, 1				; 长度减一

		cmp ebx, 3
		jne next		; 只要有一个不是3,就向深处递归,从第一个不是3的后面位置开始
	loop lp3

	; 能运行到这儿说明存在3个连续的1
	mov eax,1
	jmp return
	
	next:
	mov p, esi
	mov n, edx
	invoke FindThrees, p, n

	return:
	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	ret
FindThrees endp


END main

3-不同输入

image-20220608115603461

Write a procedure named DifferentInputs that returns EAX = 1 if the values of its three input parameters are all different; otherwise, return with EAX = 0. Use the PROC directive with a parameter list when declaring the procedure. Create a PROTO declaration for your procedure,and call it from a test program that passes different inputs

include Irvine32.inc

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
DifferentInputs proto p:PTR DWORD, n:DWORD

.data
	arr sdword 3,3,4


.code

main PROC
   ;push OFFSET nums
   ;push LENGTHOF nums
   ;call  FindLargest

	invoke DifferentInputs, ADDR arr,3
	call WriteDec
	call Crlf
	invoke ExitProcess,0
main ENDP

DifferentInputs PROC p:PTR DWORD, n:DWORD
push ebx
push ecx
push edx
push esi
push edi
	
	mov eax,0
	mov ecx, n
	mov ebx, [esi]
	mov edx, 0
	lp:
	or edx, [esi]
	add esi, TYPE DWORD
	loop lp
	cmp ebx, edx
	jne return
	mov eax,1
return:
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
DifferentInputs ENDP

END main

Exercise-13

Coursework2

; 循环判断是不是质数


include Irvine32.inc

.386
.model flat,stdcall
.stack 4096

ExitProcess proto,dwExitCode:dword

isPrime proto number:DWORD
addPrime proto pNum:DWORD
; dumpPrime proto p:PTR DWORD, t:DWORD

.data
	len = 50
	line DWORD 10
	primeArr SDWORD 0 DUP(len)
	pNow SDWORD 2
.code
main PROC
	;call Crlf

	; ecx 保存 循环次数(质数个数)
	mov ecx, len
	mov esi, OFFSET [primeArr]
	lp:
	push ecx
	;--------------------
	; 判断是不是质数,如果是返回1,否则0
	invoke isPrime, pNow
	pop ecx
	sub ecx, eax
	push ecx
	; 如果是质数就添加
	invoke addPrime, pNow
	; pNow自增
	mov ebx, pNow
	inc ebx
	mov pNow, ebx
	;---------------
	pop ecx	; 把ecx取出来
	inc ecx	; 循环次数加一
	loop lp


	exit

main ENDP

; 判断是不是质数,
; 注意:n从2开始可以不不额外判断是不是1
isPrime PROC n:DWORD
		; 特殊情况,为1或2
        mov eax, n
		cmp eax, 1
		je _notPrime
		cmp eax, 2
		je _prime

		mov ecx, n
		sub ecx, 2 ;1和本身略过,n为2时一定会执行一次

		mov ebx, n
		dec ebx
		lp:
			mov edx, 0
			mov eax, n
			div ebx
			; 只要能找到一个整除的,就不是质数
			cmp edx, 0
			je _notPrime

			dec ebx
		loop lp

		_prime:
		mov eax, 1
		ret
		_notPrime:
		mov eax, 0
		ret
isPrime ENDP

; 将n添加到质数表中
addPrime PROC n:DWORD
	cmp eax, 1
	je _add
	; 如果不相等就直接退出
	ret
	_add:
		mov eax, n
		mov DWORD PTR [esi], eax
		add esi, TYPE DWORD

	_dump:;打印质数
		call WriteInt
		; line--
		mov edx, line
		dec edx
		mov line, edx
		cmp line, 0
		je _newLine

		mov al,' '
		call WriteChar
		ret

	_newLine:	
		mov edx, 10
		mov line, edx
		call Crlf
	ret
addPrime ENDP


;dumpPrime PROC p:PTR DWORD, t:DWORD
;	mov eax, 0
;	mov ebx, 10
;	mov ecx, t
;	mov esi, p
;
;	lp:
;	push ecx
;		mov eax, [esi]
;		call WriteInt
;		add esi, TYPE DWORD
;		call Crlf
;	pop ecx
;	loop lp
;
;	ret
;dumpPrime ENDP

END main

image-20220614004832436

; 循环判断是不是质数


include Irvine32.inc

ExitProcess proto,dwExitCode:dword

isPrime proto number:DWORD
addPrime proto pNum:DWORD
dumpPrime proto

.data
	len = 50
	primeArr DWORD 0 DUP(len)
	pNow DWORD 2
.code
main PROC
	; ecx 保存 循环次数(质数个数)
	mov ecx, len
	mov esi, OFFSET [primeArr]
	lp:
	push ecx
	;--------------------
	; 判断是不是质数,如果是返回1,否则0
	invoke isPrime, pNow
	pop ecx
	sub ecx, eax
	push ecx
	; 如果是质数就添加,会使用到eax
	invoke addPrime, pNow
	; pNow自增
	mov ebx, pNow
	inc ebx
	mov pNow, ebx
	;---------------
	pop ecx	; 把ecx取出来
	inc ecx	; 循环次数加一
	loop lp

	; 输出数组
	invoke dumpPrime
	invoke ExitProcess,0

main ENDP

; 判断是不是质数,
; 注意:n从2开始不需要额外判断是不是1
isPrime PROC n:DWORD
        mov eax, n
		cmp eax, 1
		je _notPrime
		cmp eax, 2
		je _prime

		mov ecx, n
		sub ecx, 2 ;1和本身略过

		mov ebx, n
		dec ebx
		lp:
			mov edx, 0
			mov eax, n
			div ebx
			cmp edx, 0
			je _notPrime
			cmp ecx, 1
			je _prime
			dec ebx
		loop lp

		_prime:
		mov eax, 1
		ret
		_notPrime:
		mov eax, 0
		ret
isPrime ENDP

; 将n添加到质数表中
addPrime PROC n:DWORD
	cmp eax, 1
	je _add
	; 如果不相等就直接退出
	ret
	_add:
	mov eax, n
	mov DWORD PTR [esi], eax
	add esi, TYPE DWORD

	dec ecx


	ret
addPrime ENDP


dumpPrime PROC
	ret
dumpPrime ENDP

END main
; 循环判断是不是质数


include Irvine32.inc

.386
.model flat,stdcall
.stack 4096

ExitProcess proto,dwExitCode:dword

isPrime proto number:DWORD
addPrime proto pNum:DWORD
dumpPrime proto p:PTR DWORD, t:DWORD

.data
	len = 50
	primeArr SDWORD 0 DUP(len)
	place SDWORD primeArr
	pNow SDWORD 2

.code
main PROC
	; ecx 保存 循环次数(质数个数)
	mov ecx, len
	mov esi, OFFSET [primeArr]
	lp:
	push ecx
	;--------------------
	; 判断是不是质数,如果是返回1,否则0
	invoke isPrime, pNow
	pop ecx
	sub ecx, eax
	push ecx
	; 如果是质数就添加
	invoke addPrime, pNow
	; pNow自增
	mov ebx, pNow
	inc ebx
	mov pNow, ebx
	;---------------
	pop ecx	; 把ecx取出来
	inc ecx	; 循环次数加一
	loop lp

	; 输出数组
	invoke dumpPrime, ADDR primeArr, len

	invoke ExitProcess,0

main ENDP

; 判断是不是质数,
; 注意:n从2开始不需要额外判断是不是1
isPrime PROC n:DWORD
        mov eax, n
		cmp eax, 1
		je _notPrime
		cmp eax, 2
		je _prime

		mov ecx, n
		sub ecx, 2 ;1和本身略过

		mov ebx, n
		dec ebx
		lp:
			mov edx, 0
			mov eax, n
			div ebx
			cmp edx, 0
			je _notPrime
			cmp ecx, 1
			je _prime
			dec ebx
		loop lp

		_prime:
		mov eax, 1
		ret
		_notPrime:
		mov eax, 0
		ret
isPrime ENDP

; 将n添加到质数表中
addPrime PROC n:DWORD
	cmp eax, 1
	je _add
	; 如果不相等就直接退出
	ret
	_add:
	mov eax, n
	mov DWORD PTR [esi], eax
	add esi, TYPE DWORD

	dec ecx


	ret
addPrime ENDP


dumpPrime PROC p:PTR DWORD, t:DWORD
	mov eax, 0
	mov ebx, 10
	mov ecx, t
	mov esi, p

	lp:
	push ecx
		mov eax, [esi]
		mov  eax,216543
		call WriteInt
		add esi, TYPE DWORD
		call Crlf
	pop ecx
	loop lp

	ret
dumpPrime ENDP

END main

其他有意思的代码

自己的

循环打印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