这个汇编程序100例是死循环吗?求大神

C语言求大神,这个简单程序为什么是一个死循环?
[问题点数:40分,结帖人qq_]
C语言求大神,这个简单程序为什么是一个死循环?
[问题点数:40分,结帖人qq_]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2016年5月 总版技术专家分月排行榜第二
2016年10月优秀大版主2016年8月论坛优秀大版主
2018年1月 总版技术专家分月排行榜第一2016年12月 总版技术专家分月排行榜第一2016年11月 总版技术专家分月排行榜第一2016年10月 总版技术专家分月排行榜第一
2016年10月优秀大版主2016年8月优秀大版主
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
匿名用户不能发表回复!|汇编论坛 - 编程论坛 - 手机版
前天 17:56上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系。
由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇编来调用C函数,当然就要知道参数的压栈情况了。
当知道C函数的参数压栈顺序是从右到左时,我觉得很奇怪,因为大多数情况下,人们的习惯是从左到右的,难不成设计者学咱们中国古代写字从右到左的习惯不成?
当时只是记下了这个规则而已,并没有去探究这其中的缘由,后来在实验中自己用汇编实现了printf和scanf函数的基本功能,尝到了压栈从右到左的好处,但是仍然没有多想。
直到前阵子看斯坦福大学公开课的时候,老师解释了一番才恍然大悟!
那么,这是为什么呢?
要回答这个问题,就不得不谈一谈printf()函数,printf函数的原型是:printf(const char* format,&)
没错,它是一个不定参函数,那么我们在实际使用中是怎么样知道它的参数个数呢?这就要靠format了,编译器通过format中的%占位符的个数来确定参数的个数。
现在我们假设参数的压栈顺序是从左到右的,这时,函数调用的时候,format最先进栈,之后是各个参数进栈,最后pc进栈,此时,由于format先进栈了,上面压着未知个数的参数,想要知道参数的个数,必须找到format,而要找到format,必须要知道参数的个数,这样就陷入了一个无法求解的死循环了!!
而如果把参数从右到左压栈,情况又是怎么样的?函数调用时,先把若干个参数都压入栈中,再压format,最后压pc,这样一来,栈顶指针加2便找到了format,通过format中的%占位符,取得后面参数的个数,从而正确取得所有参数。
所以,如果不存在&这种不定参的函数,则参数的压栈顺序无论是从左到右还是从右到左都是没关系的。
http://m.blog.csdn.net/article/details?id=
Views(...) Comments()3.1.2 as86汇编语言程序
】 浏览:710次
3.1.2& as86汇编语言程序
下面以一个简单的框架示例程序boot.s来说明as86汇序的结构以及程序中语句的语法,然后给出编译链接和运行方法,最后分别列出as86和ld86的使用方法和编制选项。示例程序如下:
&1 !2 ! boot.s --& bootsect.S的框架程序。用代码0x07替换串msg1中1字符,然后在屏幕第1行上显示。3 ! 4 .globl begtext,begdata,begbss,endtext,enddata,endbss& ! 全局标识符,供ld86链接使用。5 .text&! 正文段。6 begtext:7 .data&! 数据段。8 begdata:9 .bss &! 未初始化数据段。10 begbss:11 .text&! 正文段。12 BOOTSEG = 0x07c0&! BIOS加载bootsect代码的原始段地址。13 14 entry start&! 告知链接程序,程序从start标号处开始执行。15 start:16 jmpi go,BOOTSEG&! 段间跳转。BOOTSEG指出跳转段地址,标号go是偏移地址。17 go:& mov& ax,cs& &! 段寄存器cs值--&ax,用于初始化数据段寄存器ds和es。18 mov& ds,ax19 mov& es,ax20 mov& [msg1+17],ah& &! 0x07--&替换字符串中1个点符号,喇叭将会鸣一声。21 mov& cx,#20& &! 共显示20个字符,包括回车换行符。22 mov& dx,#0x1004&! 字符串将显示在屏幕第17行、第5列处。23 mov& bx,#0x000c&! 字符显示属性(红色)。24 mov& bp,#msg1&! 指向要显示的字符串(中断调用要求)。25 mov& ax,#0x1301&! 写字符串并移动光标到串结尾处。26 int& 0x10&! BIOS中断调用0x10,功能0x13,子功能01。27 loop0: jmp& loop0& &! 死循环。28 msg1:.ascii "Loading system ..."! 调用BIOS中断显示的信息。共20个ASCII码字符。29 .byte 13,10 30 .org 510 &! 表示以后语句从地址510(0x1FE)开始存放。31 .word 0xAA55& &! 有效引导扇区标志,供BIOS加载引导扇区使用。32 .text33 endtext:34 .data35 enddata:36 .bss37 endbss:
这个示例是bootsect.S的一个框架程序,能编译生成引导扇区代码。其中为了说明某些语句的使用方法,特意加入了无意义的第20行语句。
我们首先介绍该程序的功能,然后详细说明各语句的作用。该程序是一个简单的引导扇区启动程序。编译链接产生的执行程序可以放入软盘第1个扇区直接用来引导计算机启动。启动后会在屏幕第17行第5列处显示出红色字符串"Loading system…",并且光标下移一行。然后程序就在第27行上死循环。
该程序开始的3行是注释语句。在as86汇编语言程序中,凡是以感叹号"!"或分号";"开始的语句其后面均为注释文字。注释语句可以放在任何语句的后面,也可以从一个新行开始。
第4行上的".globl"是汇编指示符(或称为汇编伪指令、伪操作符)。汇编指示符均以一个字符"."开始,并且不会在编译时产生任何代码。汇编指示符由一个伪操作码,后跟0个或多个操作数组成。例如第4行上的"globl"是一个伪操作码,而其后面的"begtext, begdata, begbss"等标号就是它的操作数。标号是后面带冒号的标识符,如第6行上的begtext:。但是在引用一个标号时无须带冒号。
通常,各汇编器都支持很多不同的伪操作符,但是下面仅说明Linux系统bootsect.S和setup.s汇编语言程序用到的和一些常用的as86伪操作符。
.globl伪操作符用于定义随后的标号标识符是外部的或全局的,并且即使不使用也强制引入。
第5行~11行上除定义了3个标号外,还定义了3个伪操作符:.text、.data、.bss。它们分别对应汇序编译产生目标文件中的3个段,即正文段、数据段和未初始化数据段。.text用于标识正文段的开始位置,并把当前段切换到text段;.data用于标识数据段的开始位置,并把当前段切换到data段;而.bss则用于标识一个未初始化数据段的开始,并把当前段改变成bss段。因此行5~11用于在每个段中定义一个标号,最后再切换到text段开始编写随后的代码。这里把3个段都定义在同一重叠地址范围中,因此本示例程序实际上不分段。
第12行定义了一个赋值语句"BOOTSEG = 0x07c0"。等号"="(或符号EQU)用于定义标识符BOOTSEG所代表的值,因此这个标识符可称为符号常量。这个值与中的写法一样,可以使用十进制、八进制和十六进制。
第14行上的标识符entry是保留关键字,用于迫使链接器ld86在生成的可执行文件中包括进其后指定的标号start。通常在链接多个目标文件生成一个可执行文件时应该在其中一个汇编程序中用关键词entry指定一个入口标号,以便调试。但是在我们这个示例中以及Linux内核boot/bootsect.S和boot/setup.s汇编程序中完全可以省略这个关键词,因为我们并不希望在生成的纯二进制执行文件中包括任何符号信息。
第16行上是一个段间(Inter-segment)远跳转语句,就跳转到下一条指令。由于当BIOS把程序加载到物理内存0x7c00处并跳转到该处时,所有段寄存器(包括CS)默认值均为0,即此时CS:IP=0xc00。因此这里使用段间跳转语句就是为了给CS赋段值0x7c0。该语句执行后CS:IP = 0x07C0:0x0005。随后的两条语句分别给DS和ES段寄存器赋值,让它们都指向0x7c0段。这样便于对程序中的数据(字符串)进行寻址。
第20行上的MOV指令用于把ah寄存器中0x7c0段值的高字节(0x07)存放到内存中字符串msg1最后一个"."位置处。这个字符将导致BIOS中断在显示字符串时鸣叫一声。使用这条语句主要是为了说明间接操作数的用法。在as86中,间接操作数需要使用方括号对。另外一些寻址方式如下:
! 直接寄存器寻址。跳转到bx值指定的地址处,即把bx的值复制到IP中。mov& &&bx,axjmp &bx! 间接寄存器寻址。bx值指定内存位置处的内容作为跳转的地址。mov &[bx],axjmp &[bx]! 把立即数1234放到ax中。把msg1地址值放到ax中。mov &ax,#1234mov &ax,#msg1! 绝对寻址。把内存地址1234(msg1)处的内容放入ax中。mov&ax,1234mov&ax,msg1mov&ax,[msg1]! 索引寻址。把第2个操作数所指内存位置处的值放入ax中。mov&ax,msg1[bx]mov&ax,mgs1[bx*4+si]
第21~25行的语句分别用于把立即数放到相应的寄存器中。立即数前一定要加井号"#",否则将作为内存地址使用而使语句变成绝对寻址语句,见上面示例。另外,把一个标号(如msg1)的地址值放入寄存器中时也一定要在前面加"#",否则会变成把msg1地址处的内容放到寄存器中。
第26行是BIOS屏幕显示中断调用int 0x10。这里使用其功能19、子功能1。该中断的作用是把一字符串(msg1)写到屏幕指定位置处。寄存器cx中是字符串长度值,dx中是显示位置值,bx中是显示使用的字符属性,es:bp指向字符串。
第27行是一个跳转语句,跳转到当前指令处。因此这是一个死循环语句。这里采用死循环语句是为了让显示的内容能够停留在屏幕上而不被删除。死循环语句是调试汇编程序时常用的方法。
第28~29行定义了字符串msg1。定义字符串需要使用伪操作符.ascii,并且需要使用双引号括住字符串。伪操作符.asciiz还会自动在字符串后添加一个NULL(0)字符。另外,第29行上定义了回车和换行(13,10)两个字符。定义字符需要使用伪操作符.byte,并且需要使用单引号把字符括住,如"'D'"。当然我们也可以像示例中一样直接写出字符的ASCII码。
第30行上的伪操作符语句.org定义了当前汇编的位置。这条语句会把汇编器编译过程中当前段的位置计数器值调整为该伪操作符语句上给出的值。对于本示例程序,该语句把位置计数器设置为510,并在此处(第31行)放置了有效引导扇区标志字0xAA55。伪操作符.word用于在当前位置定义一个双字节内存对象(变量),其后可以是一个数或者是一个表达式。由于后面没有代码或数据了,因此我们可以据此确定boot.s编译出来的执行程序应该正好为512B。
第32~37行又在3个段中分别放置了3个标号。分别用来表示3个段的结束位置。这样设置可以用来在链接多个目标模块时区分各个模块中各段的开始和结束位置。由于内核中的bootsect.S和setup.s程序都是单独编译链接的程序,各自期望生成的都是纯二进制文件而并没有与其他目标模块文件进行链接,因此示例程序中声明各个段的伪操作符(.text、.data和.bss)都完全可以省略,即把程序中第4~11行和32~37行全部删除也能编译链接产生出正确的结果。
【】【】【】
【】【】【】
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_80
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_83
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_78
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_12
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_09
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_10
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_81
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_75
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_87
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_45
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_9
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3
<div style="font-size:13text-align:height:14padding:0font-weight:"
id="DiggNum_3

我要回帖

更多关于 经典汇编程序100例 的文章

 

随机推荐