X86汇编-汇编程序设计1作业

1. 编写完整源程序,用API输入一串字符串,然后将该字符串进行大小写互换(如大写则变小写,如小写则变大写),将其存储到一个数组中,并用API输出。

大小写互换主要根据ASCII中二进制编码的特点来解题

结合表格可知,大小写的区别仅在于第五位,因此仅需要将编码中的第五位进行改变就可以实现大小写变换

img

以小写变大写为例,下面给出源码

    .386
.model flat,stdcall
option casemap:none
include Stdlib.Inc
includelib Stdlib.lib
include kernel32.inc
includelib kernel32.lib

.data
string db 64 dup(0)
len db 0
s db 0
store db 64 dup(0)

.code
.startup CONSOLE
invoke Readln,offset string,offset string,64
mov len,al
mov esi,0
mov ecx,dword ptr len
circle: mov al,string[esi]
and al,11011111b
mov string[esi],al
inc esi
loop circle
invoke Readln,offset string,offset store,16
invoke Writeln,offset store
.exit 0

效果如下

img

这个题目解题过程中循环次数出现问题,究其原因,是给ecx赋值的时候是mov cl,len,仅仅改变了ecx的低字节,若原来ecx高位有值,则会出现问题

2. 编写完整源程序,用API输入一串字符串,然后将该字符串逆序存储到另一个数组中,并用API输出。

基本原理是堆栈操作,但是有很多细节需要注意

    .386
.model flat,stdcall
option casemap:none
include Stdlib.Inc
includelib Stdlib.lib
include kernel32.inc
includelib kernel32.lib

.data
string db 64 dup(0)
len db 0
store db 64 dup(0)


.code
.startup CONSOLE
invoke Readln,offset string,offset string,64
mov len,al
mov esi,0
mov ecx,dword ptr len
take: movzx eax,string[esi]
push eax
inc esi
loop take
mov esi,0
mov ecx,dword ptr len
fetch: pop eax
mov store[esi],al
inc esi
loop fetch
invoke Writeln,offset store

.exit 0

在压栈的时候,数值上必须一个字节一个字节地压栈,但是实际压栈涉及32位操作,因此属于将较小值拷贝到较大值中,用到movzx

出栈的时候情况相反,仅仅需要出栈的32位的最后八位,因此将eax的al部分存入目标地址即可

效果如下

img

实验中的问题与收获

实验过程中最无语的在于readln的使用,如果提前设置好字符串,则会很快的编写好程序

首先是对于readln的第一个参数,其实设置空数组指针就可以,这个必须有

另外对于readln之后的寄存器值,eax会记录字符串长度,对之后的循环次数有帮助

最后,在调试的时候,我开始在各个循环里调用api看输出,导致ecx被修改,循环次数出现问题

posted @ 2022-03-27 19:27  Xiaohanahahah  阅读(80)  评论(0编辑  收藏  举报