耶哥蕊特 發表於 2020-11-22 01:14:00

汇编语言2

<h1 id="汇编语言学习002">汇编语言学习002</h1>
<p>使用汇编语言实现简单的<code>字符数组</code>反向输出,以及<code>字符数组</code>的打印</p>
<pre><code>.586
.MODEL flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
include msvcrt.inc

includelib kernel32.lib
includelib user32.lib
includelib msvcrt.lib

;目标1,创建一个reverse函数,参数是一个字符串,返回byte数组
;目标2,创建一个打印数组的函数
.data
string1 byte "This is a great test!",0;以空字符结尾,
next dword 0ah
reverse byte sizeof string1 dup(0);将数组初始化为0
sourcesize byte sizeof string1
Iter1 dword 0
Iter2 byte '1','2','3','4','a','j'

.code
reverseFun proc
        movzx ecx,sourcesize
        dec ecx
        xor esi,esi
l1:
        movzx eax,string1;不能把esp置为0,esp内存储栈指针
        push eax
        inc esi
        loop l1 ;第一次循环,每一个字符都入栈
        xor esi,esi
        mov ecx,sizeof string1;确定l2的循环次数
        sub ecx,1;因为下面弹出了空字符,导致字符数组长度减一
;        pop eax;弹出空字符,这样reverse数组中的字符串不会是以空字符开头
l2:
        pop eax
        mov reverse,al
        inc esi
        loop l2 ;第二次循环,每一个字符依序存放在reverse数组中
        ret
reverseFun ENDP
print1 proc
;        mov esi,0
;        mov ecx,sizeof string1
;        movzx eax,reverse;二者大小不同,需要自动扩展
        ;mov Iter2,al
        ;push offset Iter2
;        push eax
        push offset reverse
        call crt_printf;以空字符开头的字符串不能被打印出
        add esp,4
        ret
print1 ENDP
main proc
        ;先完成方法一
        call reverseFun
        ;完成方法三,打印出倒置数组
        call print1
        push offset next   ;换行,要注意的是,它不能直接压0ah
        call crt_printf      ;
        add esp,4                       ;
        push offset string1
        call crt_printf
        add esp,4
        push offset next    ;换行
        call crt_printf   ;
        add esp,4         ;
        push offset reverse
        call crt_printf
        add esp,4
        push offset next    ;换行
        call crt_printf   ;
        add esp,4         ;

        mov ecx,offset lengthof Iter2
        mov esi,ecx   ;保存ecx,因为每次ecx在函数调用后都会改变,因此需要恢复
        xor ebx,ebx
l4:
        movzx eax,;eax中存放的是Iter2中的对应位置的值
        inc ebx
        mov Iter1,eax ;将eax的值放进Iter1中
        push offset Iter1 ;将Iter2中的值,一个一个拿出来打印
;        push eax;这样的运行时call会报错,这样就是直接将eax里面的值当做地址
        call crt_printf
        add esp,4
        push offset next    ;换行
        call crt_printf   ;
        add esp,4         ;
        mov ecx,esi   ;恢复ecx,因为每次循环后都会导致ecx自动减一,所以不能先将esi的值减一
        sub esi,1          ;将esi的值减一,这意味着下一次ecx恢复时,能够是正确的值
        loop l4   
        push 0
        call ExitProcess
main ENDP
END main
</code></pre>
<p>运行结果:</p>
<pre><code>!tset taerg a si sihT
This is a great test!
!tset taerg a si sihT
1
2
3
4
a
j

</code></pre>
<p>一些笔记</p>
<pre><code>计算数组长度
.data
numArray dword 0,1,2,3,4,5
.code
main proc
        mov eax,offset lengthof numArray
       
取出数组中的值(一次循环)
        movzx eax,;eax中存放的是Iter2中的对应位置的值
        inc ebx
        mov Iter1,eax ;将eax的值放进Iter1中
        push offset Iter1 ;将Iter2中的值,一个一个拿出来打印
;        push eax;这样的运行时call会报错,这样就是直接将eax里面的值当做地址
        call crt_printf
        add esp,4
        push offset next    ;换行
        call crt_printf   ;
        add esp,4         ;
        mov ecx,esi   ;恢复ecx,因为每次循环后都会导致ecx自动减一,所以不能先将esi的值减一
        sub esi,1       
</code></pre>
<p>今天主要学习了函数的调用以及类型的声明,简单了解了循环的实现。</p><br><br>
来源:https://www.cnblogs.com/youxunle/p/14018106.html
頁: [1]
查看完整版本: 汇编语言2