汇编入门小例子

:HelloWorld

DATA SEGMENT
str db ‘Hello World 结尾
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA ;将CS和CODE,DS和DATA段建立联系
START:
MOV BX,DATA
MOV DS,BX
LEA DX,str
MOV AH,9
INT 21H

   MOV AH,4CH        ;将控制权返回给终端。
   INT 21H

CODE ENDS
END START
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
备注:
1:
MOV BX,DATA
MOV DS,BX
将数据段的值给DS寄存器,但是不能直接 MOV DS,DATA,因为mov操作中不允许将立即数给DS。
2:LEA指令:将源操作数的地址移入目的操作数。
LEA BX,Buffer
源操作数:必须是一个存储器操作数
目的操作数:16位通用寄存器
3:mov AH,9 ;使用9号系统调用从DX中读取字符串输出
int 21H; 产生系统中断。

2:从键盘输入两个一位十进制数,计算两个数之和,并将结果在屏幕上显示出来。

DATA SEGMENT
INFOR1 DB ‘Please Input the First Data(<10): INFOR2DB0AH,0DH,PleaseInputtheSecondData(<10): ’ ; 0A 是 ‘\n’ 0D 是 ‘\r’,回车换行
INFOR3 DB 0AH,0DH,’The Result is:$’
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
LEA DX,INFOR1 ;输出第一条提示语句
MOV AH,09H
INT 21H

MOV AH,01H        ;1号系统调用将字符输入至AL中。
INT 21H
SUB AL,30H        ;输入的位ASCII码,所以减去48
MOV BL,AL

LEA DX,INFOR2
MOV AH,09H
INT 21H

MOV AH,01H
INT 21H
SUB AL,30H

XOR AH,AH       ;将AH清空
ADD AL,BL       
AAA             ;加法ASCII码调整指令

PUSH AX
LEA DX,INFOR3
MOV AH,09H
INT 21H

POP AX
PUSH AX
MOV DL,AH
ADD DL,30H     ;计算结束之后加上48输出。
MOV AH,02H     ;2号系统调用,输出单个字符,在汇编中想输出数字只能单个ASCII码的输出。
INT 21H
POP AX
MOV DL,AL
ADD DL,30H  
MOV AH,02H
INT 21H

MOV AH,4CH
INT 21H

CODE ENDS
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
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
备注:
1: AAA指令:加法ASCII码调整指令。

MOV AX,0007H ;AL=07H AH=00H
MOV BL,08H ;BL=08H
ADD AL,BL ;AL=0FH
AAA ;AL=05H AH=01H
1
2
3
4
5
1
2
3
4
5
3:编写一段程序比较两个字符串是否相同,相同输出MATCH!,不相同输出NO MATCH!。

思路:

先计算两个串长度,如果不同直接退出,相同执行第2步
挨个比较字符是否相同,若有不相同结束,直到比较结束全部相同
输出match
DATA SEGMENT
STR1 DB ‘ABCDEFG NEQU -STR1 ;给N赋值, -STR1表示当前位置到STR1头部的距离,也就是STR1的长度。
STR2 DB ‘BCDEFG MEQU -STR2
MESS DB ‘NO MATCH! RIGHTDBMATCH!
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA

BEGIN:
MOV AX,DATA
MOV DS,AX
MOV AX,DATA
MOV ES,AX
MOV AL,N
CMP AL,M ;比较长度是否相等,相等ZF=0,否则ZF=1
JNZ EXIT ;JNZ:jump if not zero ,zero 指的是比较结果,而不是ZF标志位的值
LEA SI,STR1
LEA DI,STR2
MOV CL,N
MOV CH,0
CLD
REPE CMPSB ;挨个比较单个字符,如果有一个不等就跳EXIT
JNZ EXIT
LEA DX,RIGHT
JMP OUT1

EXIT:
LEA DX,MESS
OUT1:
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H

CODE ENDS
END BEGIN
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
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
备注:
1:CMP指令:
不影响两个操作数的原大小,影响的是状态标志位,如果相等,ZF=1。否则ZF=0

2:JNZ指令的逻辑写出来就是下面这样

JNZ(ZF == 0) {
//如果ZF == 0 ,则跳转
}
//如果ZF == 1,则不跳转
1
2
3
4
1
2
3
4
4:汇编读写文件

输入原文件名->将文件读入预先定义好的缓冲区->输入新的文件名->将缓冲区的内容写入新文件。

(这部分代码是马辉完成的,我们共同做的汇编程序大赛http://blog.csdn.net/yangbodong22011/article/details/53716225,他负责文件读写部分,我负责加密解密算法部分)

data segment

filePath db 20,?,20 dup(?);存储原文件名称
newFilePath db 10,?,10 dup(?),00 ;存储加密或者解密的文件的路径
fileHandle db 2 dup(?);存储文件代号
fileBuffer db 10000 dup(?);文件缓冲区
fileInputTip db ‘please input source file path: ;newFileInputTipdbpleaseinputnewfilepath: ’;提示新文件路径
openErrorTip db ‘open file error !! ;readErrorTipdbreadfileerror!! ’ ;提示读文件失败
fileCount db ? ;定义实际读取的字节数

data ends

code segment
assume cs:code,ds:data

start:
mov ax,data
mov ds,ax

call openFile      ;打开文件
call readFile      ;将文件读至缓冲区
call closeFile     ;关闭文件

call createFile    ;创建新文件
call writeFile     ;写文件
call closeFile     ;关闭文件

call returnDos     ;返回DOS

;*****
;打开文件
openFile proc near
;9号功能调用,提示输入文件名
mov dx,offset fileInputTip
mov ah,9
int 21h
;10号功能调用,将文件名存储在filePath中
mov dx,offset filePath
mov ah,10
int 21h
;换行处理
call nextLine
;取得键盘上输入的实际的个数
lea bx,filePath+1
; 清空cx
xor cx,cx
;将键盘上实际输入的个数送给cx
mov cl,[bx]
;取得文件实际的存储路径
lea bx,filePath+2
;处理enter的ascall码
call findEnter
;系统调用,打开文件
mov ah,3dh
mov al,00
lea dx,filePath+2
int 21h
; 若CF为1,打开失败
jc openError
;若CF为0,打开成功,获取返回的ax中的文件代号
jmp getFileHandle
getFileHandle:
;取得fileHandle的地址空间
lea bx,fileHandle
;将文件代号保存在fileHandle中
mov [bx],ax
ret
openError:
;9号功能调用,提示打开文件失败
mov dx,offset openErrorTip
mov ah,9
int 21h
;返回dos
call returnDos
ret
openFile endp
;*****

;*****
;读文件
readFile proc near
;系统调用,读文件
mov ah,3fh
lea si,fileHandle
mov bx,[si]
mov cx,10000
lea dx,fileBuffer
int 21h
;cf=1,读文件失败,cf=0,读文件成功
;提示读取文件失败
jc readError
jmp getFileCount
getFileCount:
;将实际读取的字节数放在fileCount中
lea bx,fileCount
mov [bx],ax
ret
readError:
;9号功能调用,提示读文件失败
mov dx,offset readErrorTip
mov ah,9
int 21h
;返回dos
call returnDos
ret
readFile endp
;*****

;*****
;换行处理
nextLine proc near
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
ret
nextLine endp
;*****

;*****
;将回车所占的地址空间的值设为00h
findEnter proc near
next1:
inc bx
loop next1
mov al,00h
mov [bx],al
ret
findEnter endp
;*****

;*****
;返回dos
returnDos proc near
mov ah,4ch
int 21h
ret
returnDos endp
;*****

;*****
;关闭文件
closeFile proc near
mov ah,3eh
int 21h
ret
closeFile endp
;*****

;*****
;创建文件,cf=0,返回文件代号,保存在ax中;cf=1,创建失败
createFile proc near
create:
;9号功能调用,提示输入新的文件名加路径
mov dx,offset newFileInputTip
mov ah,9
int 21h
;10号功能调用,将新文件名艺伎路径保存在newFilePath中
mov dx,offset newFilePath
mov ah,10
int 21h
;换行处理
call nextLine
;取得newFilePath缓冲区中实际输入的字符的个数
lea bx,newFilePath+1
;清空cx
xor cx,cx
;将newFilePath缓冲区实际存储的个数送给cx
mov cl,[bx]
;判断是否输入
cmp cx,00h
;如果输入的不为空,则跳转continue
jnz continue
;如果输入的为空,则重新输入
jmp create
continue:
;取得实际的存储路径
lea bx,newFilePath+2
;处理enter的ascall码
call findEnter
;系统调用,创建文件
mov ah,3ch
mov cx,00
lea dx,newFilePath+2
int 21h
; 将文件代号保存在fileHandle中
lea si,fileHandle
mov [si],ax
ret
createFile endp
;*****

;*****
;向文件写数据
writeFile proc near
;系统调用,写文件
mov ah,40h
lea si,fileHandle
mov bx,[si]
lea di,fileCount
mov cx,[di]
lea dx,fileBuffer
int 21h
ret
writeFile endp
;*****

code ends
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
5:汇编生成随机数

8086 定时器模式生成随机数

;*****
;获取随机数 范围1-8
getRand:
xor al,al
mov ax, 0h; 间隔定时器
out 43h,al; 将0送到43h端口
in al, 40h; 将40h端口的数据送至al

mov bl, 8   ;除8 得到范围为0-7
div bl 

mov al, ah
mov ah, 0

inc al     ; 加1 得到范围为1-8

ret

;*****
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
6:汇编生成1-N共N位不重复随机数

例如生成1-8不重复的序列,比如 12435786或者43256718,结合上面生成随机数的程序完成如下。

;*****
;创建随机数并存入文件
createRandNum:
lea si,randNum1 ;randNum1是保存随机数串的字符串
mov cx,8 ;设定需要产生的个数
doRand:
push cx
createRandNumdo1: ;循环产生
call getRand ;获得一个随机数

        xor di,di
        xor cx,cx

        lea di,randNum1
        mov cx,8
        createRandNumdo2:  ;将新产生的数字和已经保存的比对
            mov bh,[di]
            cmp bh,al 
            jz createRandNumdo1   ;如果出现重复就继续产生
            inc di
            loop createRandNumdo2

    mov bh,RandNum[0]         ;保存目前一共产生的随机数个数
    add bh,1
    mov RandNum[0],bh

    cmp bh,9               ;如果为Num+1 就结束
    jz mRet

    mov [si],al
    inc si


    pop cx
loop doRand

;*****
;获取随机数 范围1-8
getRand:
xor al,al
mov ax, 0h; 间隔定时器
out 43h,al; 将0送到43h端口
in al, 40h; 将40h端口的数据送至al

mov bl, 8   ;除8 得到范围为0-7
div bl 

mov al, ah
mov ah, 0

inc al     ; 加1 得到范围为1-8

ret

;*****

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
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
7:将一个db类型的每一位取出来保存进一个8个db大小的字符串。

例如 A的二进制是01000001我们将它每一位分别保存进一个db,得到0 1 0 0 0 0 0 1 ,将其保存入temp1

fetchBinary:
xor dx,dx;

lea si,temp1 
mov dl,[bx]

mov dh,dl;    
and dh,10000000B    ;先拿出最高位是不是1
cmp dh,00H          ;如果为0
jz _1   
mov dh,01h          ;如果不为0就置为1
_1:
mov [si],dh         ;将dh的值也就是0给[si]
inc si

mov dh,dl  
and dh,01000000B
cmp dh,00H
jz _2
mov dh,01H
_2:
mov [si],dh
inc si

mov dh,dl  
and dh,00100000B
cmp dh,0
jz _3
mov dh,01H
_3:
mov [si],dh
inc si

mov dh,dl 
and dh,00010000B
cmp dh,00H
jz _4
mov dh,01h
_4:
mov [si],dh
inc si

mov dh,dl  
and dh,00001000B
cmp dh,00H
jz _5
mov dh,01h
_5:
mov [si],dh
inc si

mov dh,dl  
and dh,00000100B
cmp dh,00H
jz _6
mov dh,01h
_6:
mov [si],dh
inc si

mov dh,dl  
and dh,00000010B
cmp dh,00H
jz _7
mov dh,01h
_7:
mov [si],dh
inc si

mov dh,dl  
and dh,00000001B
cmp dh,00H
jz _8
mov dh,01h
_8:
mov [si],dh

ret

;*****

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值