汇编语言程序设计(AT&T
Intel汇编语言程序设计(第五版)chapt_02

S4 S1 1 2 3 I-1 I-2 I-3 I-4 I-1 I-2 I-3 I-4 I-1 I-2 I-3 I-4 I-1 I-1 I-3 I-3 I-2 I-2 I-4 I-4 I-1 I-2 I-3 I-4 I-1 I-2 I-3 I-4 S2 S3 u v S5 S6
Cycles
(c) Pearson Education, 2006-2007. All rights reserved. You may modify and copy this slide show for your personal use, or for use in the classroom, as long as this copyright statement, the author's name, and the title are not changed.
Assembly Language for Intel-Based IntelComputers, 5th Edition
Kip Irvine
Chapter 2: IA-32 Processor Architecture
Slides prepared by the author
Revision date: June 4, 2006
Irvine, Kip R. Assembly Language for Intel-Based Computers 5/e, 2007.
Web site
Examples
9
Wasted Cycles (pipelined)
When one of the stages requires two or more clock cycles, clock cycles are again wasted.
汇编语言(微机)第三章

汇编语言源程序的格式
一般情况下,定位类型、组合类型和类别说明可以 不用。 注意:SEGMENT和ENDS语句必须成对使用。 例:定义一数据段DATA
DATA SEGMENT A DB '1234' B DW 12H
DATA ENDS
22
汇编语言源程序的格式
(2)偏移地址定位语句 ORG 格式:ORG 数值表达式 功能:指定在它之后的程序段或数据块所存放的起始地 址的偏移量。
SUB1: ?
RESU: ?
?
31
汇编语言源程序的格式
④ 用DUP重复因子初始化一个数据区
格式:N DUP (表达式)
?、数值、
数值表达式
重复次数 重复装入的内容
字符等
例1: DA1 DB 2 DUP(0) DA2 DB 2 DUP(‘AB’) DA3 DW 2 DUP(1)
DA1
00
00
DA2
41
LOP: ADD AL,[BX] ADC AH,0 INC BX LOOP LOP MOV [DI] ,AX MOV AH ,4CH INT 21H
CODE ENDS END START
9
汇编语言源程序的格式
汇编语言源程序的格式
二、指令性语句 [标号:] 操作码 [操作数] [;注释项]
操作码:指明操作的性质,说明计算机要执行的具体操 作。用助记符表示。
第三章:8086汇编语言程序设计
主讲教师:范新民
整理ppt
1
8086汇编语言程序设计
1 3.2.1 汇编语言源程序的格式 2 3.2.2 常量、标识符和表达式 3 3.2.3 指示性语句 4 3.2.4 指令性语句 5 3.2.5 宏指令
Intel汇编语言程序设计(第五版)chapt_05

Irvine, Kip R. Assembly Language for Intel-Based Computers 5/e, 2007.
Web site
Examples
7
Library Procedures - Overview (1 of 4)
CloseFile – Closes an open disk file Clrscr - Clears console, locates cursor at upper left corner CreateOutputFile - Creates new disk file for writing in output mode Crlf - Writes end of line sequence to standard output Delay - Pauses program execution for n millisecond interval DumpMem - Writes block of memory to standard output in hex DumpRegs – Displays general-purpose registers and flags (hex) GetCommandtail - Copies command-line args into array of bytes GetMaxXY - Gets number of cols, rows in console window buffer GetMseconds - Returns milliseconds elapsed since midnight
(c) Pearson Education, 2002. All rights reserved. You may modify and copy this slide show for your personal use, or for use in the classroom, as long as this copyright statement, the author's name, and the title are not changed.
第4章8086,8088微机汇编语言程序设计

2)段内偏移量(Offset) 它是标号与段起始地址之间相距的字节数,为一16位 无符号数。 3)类型(Type) 类型表示该标号所代表的指令的转移范围,分NEA R(近)与FAR(远)两种。NEAR类型的标号仅在 同一段内使用,用2字节指针给出转移的偏移量属性(即 只改变IP值,不改变CS值);而FAR类型的标号无此限 制,必须用4字节指针指出转移的段地址与段内偏移量。 当标号用作JMP或CALL等指令的目标操作数时,若 为段内转移或调用则采用NEAR类型;若为段间转移或 调用则应当采用FAR类型。 JMP FAR PTR LINE
第4章 8086/8088汇编语言程序设计
汇编语言程序设计是开发微机系统软件的基本 功,在程序设计中占有十分重要的地位。
由于汇编语言具有执行速度快和易于实现对硬件的控 制等独特的优点,所以至今它仍然是用户使用得较多的程 序设计语言。特别是在对于程序的空间和时间要求很高的 场合,以及需要直接控制设备的应用场合,汇编语言更是必 不可少了。 由于汇编语言本身的特点,本章将选择目前国内广泛 使用的IBM PC机作为基础机型,着重讨论8086/8088汇编 语言的基本语法规则和程序设计的基本方法,以掌握一般 汇编语言程序设计的初步技术。
(1)立即操作数 立即操作数在指令中直接给出,不需要使用 寄存器,也不涉及访问数据区的操作,只能作为 源操作数。立即操作数是整数,可以是1字节或 2字节。在汇编语言中,立即操作数用常量(包 括数值常量和符号常量)以及由常量与有关运算 符组成的数值表达式表示。 如:MOV BX,1000+5*3 (2)寄存器操作数 通用寄存器AX、BX、CX、DX、BP、 SP、DI、SI以及段寄存器CS、SS、D S、ES都可以作为操作数。如:MOV BX,AX
汇编语言

1.1.2 汇编语言
汇编指令-用能反映机器指令功能的单 词或词组来代替机器指令的操作码,用 相应的符号表示CPU内部资源和内存的 操作数 例:汇编指令: movl %esp,%ebp 二进制机器指令为: 1000100111100101 十六进制机器指令为: 89 E5
1.1.2 汇编语言
汇编语言是汇编指令集、伪指令集及其 使用规则的统称。 用汇编语言编写的程序称作汇编语言程 序,或汇编语言源程序 汇编语言源程序必须经过翻译才能变成 可执行的机器语言程序,这个翻译过程 称作汇编。
1.2.3 学习Linux环境的汇编语言 学习Linux环境的汇编语言
Linux是GNU的一员,遵循公共版权许 可证(GPL) ,是一款免费的操作系统 Linux是计算机爱好者自己的操作系统 自由的思想,开放的源码 GNU项目为Linux系统提供了丰富的程 序开发环境。我们可以使用的有GNU 汇编器gas,连接器ld、调试器gdb以及 C语言编译器gcc等
1.1.4 汇编语言的主要特性
与机器的相关性 执行的高效性 编写源程序的繁琐性 调试的复杂性 硬件控制的直接性
1.2.1 汇编语言的主要应用
程序要求具有较快的执行时间,或者只 能占用较小的存储容量 程序与计算机硬件密切相关,程序要直 接有效地控制硬件 大型软件需要提高性能、优化处理的部 分 没有合适的高级语言的时候 系统的底层软件、加密解密软件、分析 和防治计算机病毒等
1.1.3 高级语言与汇编语言
高级程序设计语言(high-level language, HLL)使用接近于人类自然语言的语法 习惯及数学表达形式 可读性、可移植性好,编写和调试程序 相对容易,编程效率高 产生的目标程序的效率不高,很难对硬 件直接加以控制
汇编综合性实验报告

实验报告一、实验目的《汇编语言程序设计》是计算机专业的重要的专业基础课,通过本综合性、设计性实验使学生进一步巩固课堂所学,全面熟悉、掌握8088宏汇编语言程序设计的基本方法和技巧,进一步提高编写程序、阅读分析程序及上机操作、调试程序的能力。
二、实验要求用键盘选择计算机演奏乐曲,程序运行时首先在屏幕上显示出乐曲名单,当从键盘上输入乐曲的序号时,计算机则演奏所选择的乐曲,当键盘上按下Q键时,演奏结束。
三、实验原理分析(一)发音原理计算机有两种产生声音的方法,一种方法是通过I/O指令向设备寄存器(端口地址为61H)的第1位交替送1和0,使与第1位相连的扬声器脉冲门产生连续的脉冲电流,驱动扬声器发出声音。
另一种方法是利用8254(系统定时器)中的2号定时器向扬声器发送不同频率的脉冲,使之产生音调高低不同的声音,这种产生声音的方法可使计算机演奏出各种乐曲。
本程序选用定时器产生声音。
ROM BIOS中的BEEP子程序能根据BL中给出的时间计数值控制8254定时器,产生持续时间为1个或几个0.5秒、频率为896HZ的声音。
通过对BEEP的修改,可以使其产生任一频率的声音。
用汇编语言编写的程序GENSOUND,能使PC机发出指定频率和指定延迟时间的声音,它是一个很好的通用发声程序。
组成乐曲的每个音符的频率值和持续时间是乐曲发声程序所必须的两组数据,知道了音调及频率的关系后,就可以按照乐曲的乐谱将每个音符的频率和持续时间定义成两个数据表,然后编程依次取出表中的频率值和时间值,调用GENSOUND程序发出各种声音。
但GENSOUND程序产生的声音不仅与输入频率有关,而且与CPU有关。
如果80X86的工作频率为8MHZ(如IBM PS/ 2-25型),则T=125ns(1 /8MHz=125ns),那么上面程序产生的时间延迟就要短的多。
在80286中,LOOP指令只需8个执行周期,而不是17个执行周期,这也会使延迟时间缩短很多。
AT&T汇编参考

A T&TASM开发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可以了,但至少和硬件相关部分的代码需要使用汇编语言,另外,由于启动部分的代码有大小限制,使用精练的汇编可以缩小目标代码的尺寸。
另外,对于某些需要被经常调用的代码,使用汇编可以提高性能。
所以我们必须了解汇编语言,即使你有可能并不喜欢它。
如果你是计算机专业的话,在大学里你应该学习过Intel格式的8086/80386汇编,这里就不再讨论。
如果我们选择的OS开发工具是GCC以及GAS的话,就必须了解AT&T汇编语言语法,因为GCC/GAS只支持这种汇编语法。
本书不会去讨论8086/80386的汇编编程,这类的书籍很多,你可以参考它们。
这里只会讨论AT&T的汇编语法,以及GCC的内嵌汇编语法。
1.SyntaxRegister Reference゚引用寄存器要在寄存器号前加百分号%,如“movl%eax,%ebx”。
゚80386有如下寄存器:゚8个32-bit寄存器%eax,%ebx,%ecx,%edx,%edi,%esi,%ebp,%esp;゚8个16-bit寄存器,它们事实上是上面8个32-bit寄存器的低16位:%ax,%bx,%cx,%dx,%di,%si,%bp,%sp;゚8个8-bit寄存器:%ah,%al,%bh,%bl,%ch,%cl,%dh,%dl。
它们事实上是寄存器%ax,%bx,%cx,%dx的高8位和低8位;゚6个段寄存器:%cs(code),%ds(data),%ss(stack),%es,%fs,%gs;゚3个控制寄存器:%cr0,%cr2,%cr3;゚6个debug寄存器:%db0,%db1,%db2,%db3,%db6,%db7;゚2个测试寄存器:%tr6,%tr7;゚8个浮点寄存器栈:%st(0),%st(1),%st(2),%st(3),%st(4),%st(5),%st(6),%st(7)。
《汇编语言》作业和主要例题

*教材:机械工业出版社主编《80x86汇编语言程序设计》第2版•马力妮CH1思考题:1-2、7-8、12、14【1.1】填空题(1)把汇编语言源程序转换为相应的目标程序的翻译程序称为(),这个翻译过程称为()。
(2)汇编语言源程序经()后,形成目标文件,再经()后,形成可执行文件。
(3)()是计算机中表示信息的最小单位,8位二进制数为一个(),而()是在操作中作为一个单元处理的一组数据。
(4)BCD码有两种存储方式:()和()。
(5)8位二进制的无符号数可表示的最大范围为()。
8位二进制的带符号数可表示的最大范围为()。
【1.2】选择题(1)下面各8位二进制数的补码中,绝对值对小的是()A. 01111111B. 10000001C. 01101101D.11111111(2)补码11001000表示的十进制真值是( )A. 200B. –200C. –56D. -184(3)16位带符号数所能表示的范围是( )A.–32767~+32768B.0~65535C.-65535~+65536D.-32768~+32767(4)与100.5不相等的数据是()A. 64.8HB. 1100100.1BC. 64.5HD. 144.4Q(5)将目标程序转换为可执行程序的是()A. 编辑程序B. 汇编程序C. 连接程序D.调试程序【1.7】将下列二进制数转换为十六进制数和十进制数。
(1)101011 B(2)11010011B (3)10110101B (4)1101100B【1.8】将下列十六进制数转换为二进制数和十进制数。
(1)2DH (2)1512H (3)1C5H (4)21F0H【1.12】将下列十进制数分别用组合型BCD码和非组合型BCD码表示。
(1)35 (2)74 (3)98 (4)14【1.14】有一个8位的数值00110101,回答问题:(1)如果它是一个二进制数,它表示的十进制数是多少?(2)如果它是BCD码,它表示的数是什么?(3)如果它是ASCII码,它表示的字符是什么?CH2思考题:1-3、6--9、11-12、16书面题:10、13-15【2.1】填空题(1)微型计算机硬件系统结构主要是由三部分组成,它们是()、()、()。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汇编语言程序设计陶治江四川大学电气信息学院gcc编译器:C语言:vi test.cgcc -o test test.c./test(不用进行连接,而且不用改变生成的可执行代码的执行位)gcc –S test.c 会生成C语言的汇编代码,默认生成的文件名是:test.s使用目标文件生成汇编代码的方法:gcc –c test.c //默认生成test.o;-c表示编译或者汇编代码而不进行连接,生成目标文件objdump –d test.o //生成test.s代码汇编:.section .dataoutput:.asciz "Now my age is %d \n"age:23.int.section .text.global _start_start:noppushl agepushl $outputcall printfadd $8,%esppushl $0call exit编译:as -o test.o test.s连接:ld -dynamic-linker /lib/ld-linux.so.2 -o test -lc test.o//使用了标准C语言库函数执行:./test汇编语言的调试:gdb工具,若要调试,在编译的时候就需要添加-gstabs选项,生成调试的信息,这个编译的结果要大的多:as –gstabs –o testo test.cld -dynamic-linker /lib/ld-linux.so.2 -o test -lc test.ogdb test关于gdb的命令:run 运行程序break *_start+1设置断点next 单步执行cont continue 程序正常执行info registers 查看所有寄存器的信息print 查看具体的某个寄存器的信息 print/x $eax x十六进制t二进制d十进制x 查看具体内寸处的信息x/42cb &output 数字是要显示的字段数&内存地址c字符d十进制x十六进制字段的长度:b字节h16为半字节w32位字数据段:.data .rodata定义只读数据段,修改后会发生段错误.octa(八常用数据类型:.ascii .asciz(末尾有空字节) .byte .double .float .int字整数,16个字节).quad(四字整数,八个字节) .short定义数组:number:.int 23,34,45movl number+4,%eax //然后number+4引用的就是第二个元素,以字节为偏移量对于其他的数据类型:number:.octa 23,34,45movl number+4,%eax此时number+16引用的就是34,因为数据本身是比较小的,所以只引用了四个自己也可以读出数据,其实是不允许的。
定义静态符号:.equ num,0xamovl $num,%eax一般的使用都是作为4字节的整数使用的,可以是不同的记数进制bss段:.comm buffer,1000 (字节为单位).comm申明未初始化的数据的内存区域.lcomm申明未初始化的数据的本地内存区域,不允许本地汇编代码之外进行访问由于不需要初始化,这部分内存在汇编连接后不用关注,可执行的代码块很小数据的传送:movx source,destination 传送的目标和地址不能同时是内存x为b字节w字l双字movb %al,%bl movw %ax,%bx movl %eax,%ebx基于数组的求值,除了像上面的使用地址相加的办法,还可以的用法是:base_address(offset_address,index,size)base_address一般是数组名 offset_address一般是零,但是只能是寄存器,所以就空着index 就是元素个数)size(每个元素的字节数)关于offset_address,是可以用来访问跨数组名的数组元素的:data1:1,2,3.intdata2:4,5,6.int那么data1(12,1,4)访问的就是5,当然,前两个参数必须要放在寄存器中一个数组的循环访问:.section .rodataoutput:.asciz "The number now is:%d\n"num:12,23,4324,35.int.section .text.global _start_start:nopmovl $0,%ediloop:pushl num(,%edi,4)pushl $outputcall printfaddl $8,%espinc %edicmpl $4,%edijne looppushl $0call exit寄存器间接寻址(使用指针):对于一个普通变量value 他的地址是$value ,当一个寄存器%edi拥有这个地址时,(%edi)就是这个地址所指向的内存的值,而地址的偏移表示为4(%edi),-4(%edi)等,而($value)就是value,前者是不允许使用的。
条件传送指令:cmovx source,destination条件取决于EFLAGS 寄存器的值对于无符号数,检查的是进位标志,零标志和奇偶校验标志来判断两个数的关系的对于有符号数,检查符号标志和溢出标志来判断两个数的关系的无符号数:above below equal(同zero)carry有符号数:greater less equal sign(有符号,是负数) overflow注意:比较指令是使用第二个数来减去第一个数后来设置标记寄存器的,所以比较的时候后一个数不能使立即数:(cmpl %edi,$4就是不合法的)应用:比较出数组的最大值.section .dataoutput:.asciz "The max number now is:%d\n"num:.int12,23,35346,43,2425,346.section .text.global _start_start:nopmovl $1,%edimovl num,%eaxloop:movl num(,%edi,4),%ebxcmovgl %ebx,%eaxinc %edicmpl $6,%edijnz looppushl %eaxpushl $outputcall printfaddl $8,%esppushl $0call exit数据交换:可以不使用第三个临时交换寄存器条件下在寄存器之间或者寄存器和内存之间交换数据xchg:xchg operand1 operand2; 操作数的长度必须相等,当使用在寄存器和内存之间交换数据的时候,处理器LOCK信号被标识,防止其他过程的改动,这个过程比较耗时bswap用于反转寄存器中的字节顺序(非比特顺序),使小尾数与大尾数之间的数进行转换,操作数只能在寄存器中(似乎只用于32位的寄存器)。
xadd source,destination ,将source destination的值相交换,然后将两者相加后将结果保存在destination中,其source必须是寄存器,xadd可以添加后缀,也可以没有后缀,寄存器可以是16,32位冒泡法排序的源代码:.section .dataarray:.int 23,2345,12,5,36,457,453,3252,423,54.section .text.global _start_start:nopmovl $9,%ecxmovl $9,%ebxmovl $array,%esiloop:movl (%esi),%eaxcmpl 4(%esi),%eaxjl skipxchg %eax,4(%esi)movl %eax,(%esi)skip:addl $4,%esidec %ebxjnz loopdec %ecxjz endmovl $array,%esijmp loopend://一定要有,否则程序不能正常结束$0pushlcall exit堆栈:在堆栈中可以使用pushl popl进行四个字节的数据的压入和弹出,使用pushw popw 可以对两个字节的数据进行操作,但是要注意的是,在压入堆栈进行prinf操作的时候,默认是使用一个双字进行输出的,即两个两个字节的元素是一次输出的,当然使用ESP指针也可以进行同样的效果的操作:subl $8,%espmovl $10,4(%esp)movl $output,(%esp)当然操作完成之后还要还原堆栈:addl $8,%esp在内存中:数据元素是按照从低内存位置开始,依次向高内存的位置存放的;而堆栈却相反,堆栈被保存在内存的末尾的位置,当在里面存放数据的时候,向下增长,地址不断减少。
pusha/popa将八个16位寄存器压入弹出堆栈pushad/popad将八个32位寄存器压入弹出堆栈pushf/popf压入或者弹出EFLAGS寄存器的低16位pushfd/popfd压入或者弹出EFLAGS寄存器的全部32位跳转:短跳转:使用一个字节作为偏移地址,所以跳转的距离最多就是128个字节,远跳转是在分段内存模式下从一个段跳转到另外一个断使用的,近跳转是其他的跳转情况,在汇编指令中,只需要使用jmp 就可以了,而不用顾及跳转的距离。
调用与跳转的区别是保留了返回地址以便返回,使用ret指令返回,在执行call指令的时候,它把EIP的值放到堆栈中,然后修改EIP的值使它对到要调用的函数的地址,调用结束后从堆栈中获得EIP原先的值以便返回到原先的地址。
在实际的函数的编写的过程中是将ESP 的值复制到EIP寄存器中的,然后使用EIP寄存器的值获得在CALL指令之前传递给堆栈的信息的,并且可以将本地变量保存在堆栈中。
函数编写的模式:function_label:pushl %ebpmovl %esp,%ebp---------movl %ebp ,%esppopl %ebpret在函数中要注意对堆栈的清理:但是从函数的调用模式中可以发现,最后总是要使用movl %ebp ,%esp进行恢复的,可能不用手工恢复:.section .dataoutput:.asciz "The result is : %d \n".section .text.global _start_start:nopcall functionpushl $0call exitfunction:pushl %ebpmovl %esp,%ebppushl $10pushl $outputcall printfaddl $8,%esp //用不用??movl %ebp,%esppopl %ebpret中断:中断分为软中断和硬中断,硬中断时由硬件发出的信号(如IO操作),软中断是由操作系统提供的,可以调用操作系统的核心函数,甚至可以调用底层的BIOS层次,在Linux 中是使用0x80调用的。