汇编实验
最后一批有意思的练习题
写在前面
- 终于完成了Intel x86汇编的习题(我认为应该写的)+基础知识,基本上花了3周左右(除去假期中间的咕咕咕极长时间),可喜可贺,也该开学了。
- 不coding死路一条
- 不要停下来啊(指学习)
- 下一阶段的目标就是数学+算法+Python网络编程
- 不学数学读研死路一条
什么,你说假期里的前端学习?咕咕咕
汇编代码咋高亮啊,好像不支持…
Str_find过程
编写过程Str_find在目的串中查找第一次出现的源串,并返回其位置。输入参数为源串指针和目的指针。如果查找成功,过程将零标志位ZF置1,用EAX返回指向目的的串的匹配位置。否则ZF清零,EAX无定义。
1 | .386 |
链表
用汇编语言实现一个单项链表(课本例子)
1 | INCLUDE Irvine32.inc |
需要注意:
- 先定义一个标识头,不然到最后没有办法找到链表的起始位置
- 使用REPEAT伪指令来重复执行一个代码块,其格式如下:
REPEAT constExpression
statement
ENDM
constExpression是一个无符号整数常量,用于确定重复的次数,这里我们重复执行
Counter = Counter + 1
ListNode <Counter, $ + Counter*SIZEOF ListNode>
来填充这个链表(将NextPtr指向下一块ListNode大小的地方,由于定义时存储连续的,使用$+偏移量来指向下一个)
- 无法直接[esi].NextPtr来访问,必须使用
ListNode PTR [esi]
,因为无法表明其所属的结构
Str_trim过程拓展
Irvine32链接库里的Str_trim过程从空字节结束的字符串中移除所有与选定的尾部字符匹配的字符,这个过程的逻辑很有意思,因为程序需要检查很多种情况,以#作为尾字符为例:
1)字符串为空
2)字符串一个或多个尾字符的前面有其他字符,如"Hello#"
3)字符串只有一个字符,且为尾字符,如"#"
4)字符串不含尾部字符,如"Hello"
5)字符串在一个或多个尾部字符跟随一个或多个尾部字符,如"Hello##"
现在我们先研究一下其源码,以例子来看:
1 | INCLUDE Irvine32.inc |
为了防止和库中冲突,我修改了函数名
留意StrTrim过程,写的很巧妙,倒着匹配,匹配到就插入一个0表示结束,没有就接着比
裁剪前导字符
现在要求删去给定前导字符,如"##Hello" --> “Hello”
1 | ;只修改部分的StrTrim的代码 |
我们只需要在匹配上后把后面的依次向前移位就行,注意带上结尾的’0’
注意:mov [edi], [edi+1]
是不行的,我竟然这么写了,无法内存到内存
去除一组字符
现在要求过滤一组字符串,使主调程序能从字符串末尾删除一组字符。
分析一下就是设置一个“指针”从后向前在过滤的字符串中寻找,有就将“指针”向前移一位,直到匹配不到,这个“指针”就是间接寻址的一个寄存器
1 | StrTrim PROC USES eax ecx edi ebx esi, |