汇编语言程序设计实验一:顺序结构
第1关:加法、减法运算
任务描述
本关任务:编写一个能进行加、减运算的小程序。
编程要求
在寄存器AX,BX,CX,DX中分别存放了四个变量A,B,C,D的值,均为8位无符号数。
请编写汇编代码,计算Z=(A+B)-(C-D)的结果,并将结果ZZ保存到AX中。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:30201005
预期输出:0045
测试输入:F00F0001
预期输出:0100
测试输入的每两个字符组成一个十六进制数,分别对应要读取到AX,BX,CX,DX的值。
Cal:
;在此处编写汇编代码实现功能
add ax,bx
sub cx,dx
sub ax,cx
ret
第2关:混合四则运算
任务描述
本关任务:编写一个能进行混合四则运算的小程序。
编程要求
在寄存器AX,BX,CX,DX中分别存放了四个变量X,Y,V,ZX,Y,V,Z的值,均为16位有符号数。此外,还有一个寄存器RSI保存有变量W的地址。
请编写汇编代码,计算W=(X * Y-V)/ZW=(X∗Y−V)/Z的结果,并将商保存到W位置处,将余数保存到W+2位置处。
注意1:算式中的乘法运算不会超出16位表示范围,减法运算不会得到负数结果。
注意2:由于使用的是不同于8086的X86-64汇编,因此内存寻址不再使用段址:偏移地址的形式,而是直接使用完整地址,比如:
mov ax,0xff
mov word ds:[si], ax ;不再使用这种形式
mov word [rsi], ax ;直接使用完整地址
上述代码中的rsi为64位寄存器,si可以看作是它的低16位,就像ax和al的关系。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:0050002000100015
预期输出:00790003
测试输入:0098003200560132
预期输出:001800AA
测试输入每四个字符代表一个十六进制数,分别对应要读取到AX,BX,CX,DX的值。
预期输出的前四个字符代表商的十六进制表示,后四个字符代表余数的十六进制表示。
Cal:
push dx
imul bx
sub ax, cx
pop cx
idiv cx
mov word [rsi], ax
mov word [rsi + 2], dx
ret
汇编语言程序设计实验二:分支结构
第1关:求最大值
任务描述
本关任务:编写一个能求出三个数中最大值的小程序。
编程要求
在寄存器AX,BX,CX中存有三个16位有符号数,找出其中最大的数,并将其放在AX中。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:FF0000010020;
预期输出:
0020
测试输入:123456789ABC;
预期输出:
5678
测试输入的每四个字符组成一个十六进制数,分别对应要读取到AX,BX,CX的值。
Max:
cmp ax, bx
jg g1
mov dx, bx
mov bx, ax
mov ax, dx
g1:
cmp ax, cx
jg g2
mov dx, cx
mov cx, ax
mov ax, dx
g2:
ret
第2关:判断变量符号
任务描述
本关任务:编写一个能判断变量符号的小程序。
编程要求
根据XX计算YY的值,当X < 0X<0时Y = -1Y=−1;X = 0X=0时Y = 0Y=0;X > 0X>0时Y = 1Y=1。
请定义一个数据段,并在其中分别定义两个名为X和Y的字节型变量,长度为1个字节。
评测系统会读取输入数据,并将其放入X,然后调用学员编写的代码,最后读取并显示Y中的数据。所以学员代码需要将上面运算的结果存入Y中。
注意:平台使用的是Nasm,定义数据段的语法与Masm有所不同,它使用的是section .data来定义:
section .data ;定义数据段
var1 db 0,0 ;字节型,总长为2个字节
var2 dw 0,0,0 ;字型,总长为2*3=6个字节
section .text ;定义代码段
Prog1:
mov rsi, var1 ;将var1变量的地址存入rsi
mov ax, 0xff
mov word [rsi], ax ;向var1变量写入ax的值
测试说明
平台会对你编写的代码进行测试:
测试输入:F0;
预期输出:
FF
测试输入:00;
预期输出:
00
section .data
Y db 0
X db 0
Sign:
mov al, byte [X]
cmp al, 0
jg g0
je e0
mov al, -1
mov byte [Y], al
ret
e0:
mov al, 0
mov byte [Y], al
ret
g0:
mov al, 1
mov byte [Y], al
ret
汇编语言程序设计实验三:循环结构
第1关:求最高成绩
任务描述
本关任务:编写一个能求出多个成绩中最高成绩的小程序。
编程要求
在寄存器RSI中存放了一个字节型数组的地址,数组中存放有多个成绩数据,均为正数。在寄存器AX中则存有这个数组的长度。
请编写代码,求出这个数组中的最高成绩,并将其放入到AX中。
注意:数组的最小长度为1,最大为20。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:021030
预期输出:30
测试输入:0450346010
预期输出:60
测试输入的前两个字符是数组的长度的十六进制表示,之后每两个字符组成一个十六进制数,代表数组中的值。
Max:
mov cx, ax
mov al, byte [rsi]
find:
mov ah, byte [rsi]
cmp al, ah
jg g
mov al, ah
g:
inc rsi
loop find
ret
第2关:统计奇偶数量
任务描述
本关任务:编写一个能统计数组中奇数偶数数量的小程序。
编程要求
在寄存器RSI中存放了一个字节型数组的地址,数组中存放有多个数据,均为非负数。在寄存器AX中则存有这个数组的长度。
请编写代码,在数据段中定义一个字节型变量Result,长度为2个字节,然后统计这个数组中的奇数和偶数的数量,将偶数数量放入变量第一个字节,奇数数量放入变量第二个字节。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:03000204
预期输出:0300
测试输入:020102
预期输出:0101
测试输入的前两个字符是数组的长度的十六进制表示,之后每两个字符组成一个十六进制数,代表数组中的值。
section .data
Result db 0,0
Count:
mov cx, ax
tes:
mov al, byte [rsi]
and al, 0x01
mov rdi, Result
jz even
inc rdi
even:
mov ah, byte [rdi]
inc ah
mov byte [rdi], ah
inc rsi
loop tes
ret
汇编语言程序设计实验四:综合
第1关:字符大小写转换
测试说明
任务描述
本关任务:编写一个能将字符串中字母大小写转换的小程序。
编程要求
在寄存器RSI中存放有一个以符号$结尾的字符串的地址,请编写代码,将这个字符串中的小写字母转化为大写,大写字母转化为小写,其他字符不做处理。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:04Abc$
预期输出:aBC$
测试输入:08iPhone8$
预期输出:IpHONE8$
输入数据的前两个字符是字符串长度的十六进制表示,之后则是字符串的内容。
Conv:
mov al, byte [rsi]
cmp al, '$'
je end
cmp al,'a'
jl up
cmp al,'z'
jg loopEnd
and al, 0xDF ;小写变大写,就是将二进制表示的第6位变成0
mov byte [rsi], al
jmp loopEnd
up:
cmp al, 'A'
jl loopEnd
cmp al, 'Z'
jg loopEnd
or al, 0x20 ;大写变小写,就是将二进制表示的第6位变成1
mov byte [rsi], al
loopEnd:
inc rsi
jmp Conv
end:
ret
第2关:统计字符数量
任务描述
本关任务:编写一个能统计字符串中各种字符数量的小程序。
编程要求
在寄存器RSI中存放有一个以符号$结尾的字符串的地址,请在数据段中定义一个字节型变量Result,长度为3个字节。
然后统计这个字符串中数字,字母,其他字符(即除数字、字母外的)的数量,并将结果依次存放到Result的三个字节中。
注意:字符串末尾的$不算在内。
输入数据由评测系统读取,并存放到指定寄存器中,程序运行结果也由评测系统读取并输出,学员只需要实现任务逻辑即可。
测试说明
平台会对你编写的代码进行测试:
测试输入:041AC$
预期输出:010200
测试输入:0EHello World!$
预期输出:000A02
输入数据的前两个字符是字符串长度的十六进制表示,之后则是字符串的内容。
预期输出每两个字符组成一个十六进制数,分别代表Result变量的三个字节的内容。
section .data
Result db 0,0,0
Count:
;在ascii表中,小写字母>大写字母>数字
mov al, byte [rsi]
cmp al, '$'
je end
;判断是不是小写字母
cmp al,'z'
jg other
cmp al, 'a'
jl up
mov ah, byte [Result + 1]
inc ah
mov byte [Result + 1],ah
jmp loopEnd
up:
;判断是不是大写字母
cmp al,'Z'
jg other
cmp al,'A'
jl dig
mov ah, byte [Result + 1]
inc ah
mov byte [Result + 1],ah
jmp loopEnd
dig:
;判断是不是数字
cmp al,'9'
jg other
cmp al,'0'
jl other
mov ah, byte [Result ]
inc ah
mov byte [Result],ah
jmp loopEnd
other:
;否则是其他符号
mov ah, byte [Result + 2]
inc ah
mov byte [Result + 2],ah
loopEnd:
inc rsi
jmp Count
end:
ret