本文主要是介绍Aseembly(八)-汇编语言编写程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
在该系列的第六篇文章我们主要讲述了:关于栈的寄存器:SS和SP的问题
来回一下:
对于栈指针来说,栈在被开辟的时候,首先要通过SS指针去找到开辟栈的地址空间的首地址,随后,SP指针指向该栈空间的末尾的下一个空间处.当执行push指令时,sp会-2 随后将目标压入栈中
当执行pop指令时,会先将元素弹出,随后执行sp+2
还回顾了关于不同段寄存器的作用:
ds与[] 是读取数据
cs:ip是去寻找指令
而ss:sp与栈空间有关.
详情请看我的上一篇文章
Assembly(六)–寄存器总篇章
喜欢的小伙伴点赞关注支持一下~ 博主争取日更哦~
本篇文章我们将去透彻的理解一个完整的程序.
1.1 程序从写出到被执行的过程
- 编写汇编源程序 用汇编语言等语言编写程序的源程序
- 对原程序进行编译 link
这部分可以参照我的另一篇文章:关于C++的编译和链接的新看法
C++ - 执行可执行文件中的程序,有cs:ip指向第一条要执行的指令,然后由cpu执行程序
1.2 源程序的讲解
让我们来实际的看下一段汇编的程序吧
assume cs:codesgcodesg segment mov ax,0123Hmov bx,0456Hadd ax,bxadd ax,axmov ax,4c00Hint 21H
codesg endsend
关于程序,由以下几点要说明:
伪指令
- 程序中出现的伪指令有:xxx segment xxx ends ,这个segment与ends是成对出现的,表示定义了一个段,这个段是xxx 像是程序中的 段名叫 codesg
- end ,.end是代表着一个汇编程序的结束标志
- assume 用来假设程序的某一个段与某个寄存器相联系,比如 其中的 assume cs:codesg 这里就跟cs寄存器联系起来了
一个汇编程序通常由伪指令和汇编指令组成.经过编译链接后编程可执行文件.
练习:让我们来写一个计算2的三次方的程序吧:
assume cs:cac
cac segment mov ax,2add ax,axadd ax,ax
cac ends
end
十分简单
当我们考虑到:一个程序要有返回值时,问题就来了
1.3 程序的返回
观察之前的程序:
assume cs:codesgcodesg segment mov ax,0123Hmov bx,0456Hadd ax,bxadd ax,axmov ax,4c00Hint 21H
codesg endsend
我们不难看出有两条指令没有被提到:
mov ax,4c00H
int 21H
这两条指令所实现的功能就是程序返回
我们不必深究为什么,反转在end后面加两条指令就可以实现程序返回.
1.4 实战:
1. 在准备好的dosbox中,使用edit功能:
进行编辑
保存退出为1.asm
随后进行编译
使用masm.exe
这里先输入文件名,随后默认obj文件的名字 随后忽略文件生成列表和交叉引用文件
编译完成!
接下来开始链接:
使用link.exe
在忽略了 lib和无栈段生成后,我们成功的链接了文件.生成了exe文件
链接的作用是什么呢?
首先当程序很大的时候,可以分成多个文件来进行编译,自然链接到一起可以很方便
其次如果程序中强调了某个库文件的子程序,链接也十分必要了.
2. 编译 链接 跟踪
写文件t1.asm
assume cs:codesg
codesg segmentmov ax.2000Hmov ss,axmov sp,0add sp.10pop axpop bxpush axpush bxpop axpop bxmov ax,4c00Hint 21Hcodesg endsend
然后进行编译 链接后使用debug进行调试
可以看到目前的cs:ip是在076A:0处
此时的SS是0769 sp为0
执行两次命令后,成功的将ax的值赋值给了ss
接下来就是执行sp的赋值了
其实这里的pop ax就是为了让sp=sp+2
连着两次都是
随后进行push操作 是为了让sp=sp-2
这篇关于Aseembly(八)-汇编语言编写程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!