《汇编语言程序设计》学习笔记(4)四、汇编编程

这篇博客详细介绍了80x86汇编语言编程,从编写hello world程序开始,逐步讲解汇编指示、C程序内存布局、系统调用、处理命令行参数、调用libc库函数等。文章深入浅出地解释了汇编语言程序的结构,包括数据段、bss段,并展示了如何进行过程调用和递归调用。此外,还探讨了文件处理和内存管理,包括动态分配内存和堆管理,以及如何通过系统调用来实现这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.1 80x86汇编编程-1

4.1.1 hello world-1

目录

这里写图片描述

Hello World

这里写图片描述

这里写图片描述

这里写图片描述

首先我们来看一下咱们 这个程序的主体 首先第一个吧 虽然我们没有详细的讲解过 一个完整的汇编程序的结构 但是从这张图上我们可以基本上 猜得出来看到程序入口地址在哪 -main 因为-main 是个int C里面的一个main C程序的入口函数是main 所以这个对应的汇编函数 它的入口地址也是main main里面我们看每行干了些什么事

首先看一下 第一行和第三行 push 后边一个move 这个完全非常熟悉了 因为它还是一个C程序吗 C程序函数被调用的时候 它的入口地方呢会建立这个栈帧 就是push ebp和mov esp到 ebp 这个我们非常的熟悉

那么当中这一行mov 16 到eax 是干什么的呢 这个我也不知道 这个我也不知道 我们回头看 后来这个代码会被优化掉

后来再往下走 再往下这一条指令 这是一条减法指令 把esp减8 那这个呐 我们应该也熟悉了 就是给当前main函数一个分配 8字节的一个栈空间 esp减8吗

那这个是干嘛的呢 后来又加了一个and 为什么会有一个与操作呢 实际上把esp跟负16去 与一下 的话 就使得什么 因为负16大家都知道 用补码表示的话 它的最低四位是0 全零 它跟esp 与一下的话 就确保这个栈顶地址是16字节对齐 这一般来说 在C程序里头 我们分配栈的话 一般来说 要保这个栈顶地址要16字节对齐 对一个函数而言 经常有这样的一个约定 但这个约定是一个软件约定 可以修改的

接下来两个call 对应两个函数 这两个函数都不认识 其实这两个呢 当然跟我们汇编编程 应该关系不是特别太大 这两个函数分别都是 与C运行时库初始化相关的 这大家知道就是说 我们写个C程序吧 一般来说 C程序默认去调的libc这个库 C运行时库 你所调的一些C调用 都是在C运行时库里实现的 那么这两个函数呢 关于C运行时库初始化相关的 其中第一个呢 跟栈的分配相关 这咱们就不展开说了 跟我们关系不是太大

再往下看 似成相识 因为我们在这个原来C代码里 就调了一个printf 最后在退出时 调了一个exit 0 exit 0 好说了 就是程序退出吗 就是程序退出这个调用 那么这样的话 相当于就是说 mov 0 括号esp 实际上就设置了这个exit 这个零的 这个参数 这我们回想一下 就相当于mov零到栈顶 然后call 返回地址压栈 就去进入exit 实际上这个地方就做了一个过程调用参数 而其我们看到就是说 call(exit)之后呢 renturn(0)那个代码 在这里头没有体现 为什么呢 已经调用了exit 编译前是很聪明的 exit之后 这个代码就不给你编译了 renturn(0)就给它skip掉了 虽然前面已经写了一个了

再往下看的话呢 call puts 注意啊 我们原来调的那个函数 叫call printf用的是printf 那这个地方呢 我认为这个编译器比较聪明 printf里头我们只是用了什么 把它输出一个字符串 没有做任何格式的转化 所以它用一个puts来替换 那这样简单一点了

然后这个呢 因为相当于就是说 我们要打个hello world出发 出来 所以puts唯一的一个参数 也就是说它要打印出来的 字符串的地址 所以我们就把这个地址 lc0callputsokhelloworldprintfoklc0

一、问题描述 课题1:排序。要求从键盘上输入若干个人名,当输入完毕后,能显示正确的顺序。 课题2:编写一个类似于TT的英文打字测试程序。要求输入的字符能在屏幕上显示并报告所用时间。 二、设计思想 课题1:排序。程序分3个部分 (1) 等待用户输入数个人名,即输入字符串。本程序设定输入人名数为5到15个,运用了2个函数(input1,input2)实现。 定义 data1 db 21,0,22 dup('$') ;用于存放第一个字符串 data2 db 21,0,22 dup('$') ;用于存放第二个字符串 data3 db 21,0,22 dup('$') ;用于存放第三个字符串 data4 db 21,0,22 dup('$') ;用于存放第个字符串 data5 db 21,0,22 dup('$') ;用于存放第五个字符串 data6 db 21,0,22 dup('$') ;用于存放第六个字符串 data7 db 21,0,22 dup('$') ;用于存放第七个字符串 data8 db 21,0,22 dup('$') ;用于存放第八个字符串 data9 db 21,0,22 dup('$') ;用于存放第九个字符串 dataa db 21,0,22 dup('$') ;用于存放第十个字符串 datab db 21,0,22 dup('$') ;用于存放第十一个字符串 datac db 21,0,22 dup('$') ;用于存放第十二个字符串 datad db 21,0,22 dup('$') ;用于存放第十三个字符串 datae db 21,0,22 dup('$') ;用于存放第十个字符串 dataf db 21,0,22 dup('$') ;用于存放第十五个字符串 input1实现前五个字符串的输入,调用0A号功能实现输入,当用户没有输入字符而直接回车时,程序会判断为输入错误,直到输入字符为止,此时按下回车,会转到下个字符串的输入。 input2实现后10个字符串的输入,调用0a号功能实现输入,当用户没有输入字符而直接回车时,程序会判断用户选择结束输入,跳转出input2函数。实现了用户连续按两下回车(注意:第一个回车为前一个字符串的结束回车,此后再按一次回车就表示退出),直接退出输入的功能。 (2)人名排序,即字符串排序。 采用冒泡排序的方法,进行双重循环,内循环实现字符串的比较交换,若前一 个字符串大则跳转去交换,小或者相等则跳转去比较下两个字符串。 外循环是在内部循环结束后继续从第一个字符串开始跳转到内部循环,保证顺序排好。 另外字符串本身的比较也是一重循环,以字符串结尾符号'$'控制比较次数。 交换部分则是两个存储单元的完全交换(从第一个字符到最后一个字符)。 (3)输出排序好的人名 最后将排序好的字符串依次输出在屏幕上。 三、课程设计体会 在此次课程设计中,我与吕鑫等人一组,我们综合利用了80X86汇编语言程序设计这门课中所学的所有知识,实践操作了多种指令的功能,丰富了用汇编语言编程的经验。也从中体会到了用汇编编程的难处。 在以小组为单位的课程设计制作过程中,我与其他组员相互讨论、配合,最后共同完成了2个课题要求的程序编写,极大提升了我团队共同合作的编程经验,受益匪浅。也提高了我分析问题、解决问题的能力。 课题2:TT英文打字测试程序要求程序有3功能 (1)在屏幕上输出一条字符串; 在程序中定义几段字符串 STR1 DB 'ABCD EFGH IJKL MNOP QRST UVWX YZ.' STR2 DB 'THERE ARE SOME NEWSPAPERS ON THE TABLE.' STR3 DB 'THERE ARE SOME CLOUDS IN THE SKY.' STR4 DB 'SHE ALWAYS EATS HER LUNCH AT NOON.' STR5 DB 'I DO NOT LIKE AUTUMN AND WINTER.' 运行时,在屏幕上依次输出这几段字符串,每输出一段字符串,便开始等待用户从键盘输入字符。 (2)从键盘上读入字符,并显示在屏幕上,以回车键结束输入; 首先用 INT 21H 从键盘读入一个字符,将读入的字符放入AL中,判断该字符是否是回车,若不是回车则马上用INT 10H 在当前光标位置上显示AL中的字符,若是回车则结束从键盘上读入字符。 (3)对从键盘上读入字符的过程计时,并在输入结束后,将输入用时显示在屏幕上。 定义 SEC DW 0 ;sec表示秒钟 MIN DW 0 ;min表示分钟 HOURS DW 0 ;hours表示小时 将它们初始化为0。 输入字符结束后,依次将hours、min、mours赋值给ax,并输出在屏幕上,以分号隔开。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值