当前位置:首页 » 编程语言 » ibmpc的编译程序c语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

ibmpc的编译程序c语言

发布时间: 2022-09-06 02:15:59

1. 如何c语言与汇编混编

c语言可以嵌套汇编:
按照TC2.0的帮助系统所以说的,在TC2.0下是可以用汇编的,方法是使用asm关键字:其格式是:
asm opcode <operands> <;newline>,如同别的注释一样,<>之间的表示可选的;例如:

main()
{
char *c="hello,world/n/r$";
asm mov ah,9;asm mov dx,c;asm int 33;
printf("You sucessed!/n");

}
或者是:

main()
{
char *c="hello,world/n/r$";
asm mov ah,9
asm mov dx,c
asm int 33
printf("You sucessed!");
}
两种格式其实是一种.如果你用的是第一种的样式,记住:
每一句汇编语句都要以asm开头,如果一行内有多个句子,
那么千万不要忘记在两个句子之间的这个semicolon(分号),
但是最后一句汇编后面(如果后面没有其它的语句)的分号可有可无,象第一个例子中的
asm int 33;后面的分号就可以不要,因为它的后面没有其它
的语句了.但如果是这样:
asm mov ah,9; asm mov dx,c;asm int 33; printf("You sucessed!");
那么asm int 33;后面的分号便还是留下好,以免出现编译错误!
在这一点上颇象C语言.

还有一种格式是
asm{ assembly language statement},这种格式应该被普遍的欢迎.
它们的例子如下(其中的语句排列格式与上面两种相同):
asm{
mov ax,var1
add ax,var2
......
}
但是要注意这种格式TC2.0是不支持的!
只有后来的TC++3.0及后来的IDE支持!

工具的使用:
一旦你的C源文件里包括了这些好东西,则必须用TCC.EXE的COMMAND-LINE来编译,具体的命令参数TCC.EXE已经提供,这里不复阐述了.最简单的是:TCC C源文件名(使用这个方法,TCC会自动调用TASM.EXE和TLINK.EXE,并且能够使TLINK.EXE正确的找到需要的.obj和.lib文件,如果你单步编译的话,可能会碰到很多的问题,主要是TLINK.EXE它自己并不会去找.obj和.lib文件,你自己可以建一个.bat文件,如果要指定.lib文件的目录的话可以用/L参数,在文章的后面有一个例子).但大家要注意了,看一下你的TC目录下面到底是否有TASM.EXE文件,并在TURBOC.CFG(这个文件包括TCC.EXE运行期参数,这里面所有参数在运很期都将被自动TCC.EXE使用,例如:-IH:/TC/INCLUDE/
-LH:/TC/LIB/)文件中设置好一些参数,并确认TASM.EXE的版本号要2.0以上,以及是否能够向下兼容.但是在大多数的情况下TC的目录是没有TASM.EXE的,或是版本不正常.
如果你有TASM.EXE文件并且TURBOC.CFG文件也已经写好了,但是还要注意一个
问题:运行TCC.EXE时要在独立的DOS SHELL下面(不要害怕,这不是一个新东西,我的意思
是,不在诸如TC下的DOS SHELL下面运行,我曾经败在这个问题下,当我发现时直想揍电脑
一顿,还好没有,不然就没有这篇文件了.)
还有一句重要的话:TC2.0支持大部分8086指令(当然用法有一些约定,不过现在我并不打算
进行详细说明,因为那是一件很繁杂的事,以后有时间或许会写出来----如果大家需要的话).
如果说上面我所说的那些约定很繁杂的话,那么下面的方法该是多么简单啊!
让我们使用Borland为TC2.0内建的变量来进行伪汇编.
或许你还不知道在TC2.0中还有一些内建的pseudo寄存器(可以看作是register 型的变量,但是它们比register型的变量好用的多)
_AX,_AH,_AL,
_BX,_BH,_BL,
_CX,_CH,_CL,
_DX,_DH,_DL,
_DI,_SI,_SP,
_CS,_DS,_ES,_SS
注意这些寄存器的size,_AX,_BX,_CX,_DX,_CS,_DS,_ES,_SS,_SI,_DI,_SP等都是16位的寄存器相当于C语言的unsigned int类型,其余的都是8位的寄存器(相当于unsigned char)(TC怎么可能支持32位的寄存呢,所以EAX等是不能用的,FS,GS和IP寄存器都是无效的),还有就是在传递参数的时候千万不要忘记使用强制类型转换.
中断调用指令是:__int__(interrupt_#)(注意int的前辍和后辍都是两个underscores)
For example:
#include<dos.h>
unsigned int _stklen=0x200;
unsigned int _heaplen=0;

main()
{
_DX=(unsigned int)"Hello,world./r/n$";
_AX=0x900;
__int__(0x21);

}
dos.h它是包含__int__()内建中断调用语句的头文件,因此是不可
缺少的._stklen和_heaplen是定义运行期堆栈和堆大小的两个内部
引用变量(这是个我自己想的名词,意指如果这两个变量在源文件中
显式的声明了,那么编译程序会自会引用来构造编译时期的信息以产生
用户希望的目标文件,如果不显式的声明则编译程序自动确定).
这两个变量也有一些约定,如果_stklen不显式声明,_heaplen赋值为零
都表示栈和堆都是defult的.
最后在TC2.0中还有一个没有说明的标志位寄存器flags,它也是内建
pseudo寄存器是:_FLAGS,是一个16位寄存器.这些内建的寄存器都可以进行
运算,但是要注意它们所代表的类型(必要时进行类型转换);
看起来这是不是一种好的办法啊(而且使用这种方法只要用个一个dos.h头文件就好,
不需要用TCC编译,可以直接在TC20的IDE下编译).
TC2.0中也提供了一些简单好用的函数来实现对DOS功能的调用如:
int86(...),int86x(...)(但是这些方法实际仍然要调用函数,所以不如使用
伪寄存器,又因为要牵涉到union REGS结构的内存分配所以系统的开销是增大了,
而使用伪寄存器是最简洁的),端口通信函数如:inportb(...),inport(...),
outportb(...),outport(...),指针转换函数:FP_OFF,FP_SEG,MK_FP,这些函数在
帮助系统中都有,有用时大家可以查阅.

tlinkbat.bat的例子:
rem The lib environment variable is the directory of the .obj and .lib file
set lib=h:/tc/lib/
rem 这下面的句子中的c0s(C 零S)是一个.OBJ文件,是一个C程序的STARTUP文件
tlink %lib%c0s %1,%1,%1,/L%lib%emu.lib %lib%maths.lib %lib%cs.lib
set lib=
(使用时可将以rem开头的句子删除)

___________________________________________________
一些约定:
我们先说一下在TC20下写汇编(内联汇编--自己起的名字,大家可以想叫什么叫什么)时的编译器的编译原则:
1.所有在main()函数外的的汇编语言的语句都作为数据声明语句处理,也即在编译器编译时会将它放在数据段中,如:
asm string1 db "Hello",,,'world!',0ah,0xd,"$"
main()
{
asm mov dx,offset string1
asm mov ah,9
asm int 33
asm mov dx,offset string2
asm int 33
}
asm string2 db "the string can be declared after the main() function!$"
象这些样子在main()外面的汇编语言的数据定义语句(事实上不管是什么汇编语句,
只要是在main()之外,包括这个句子:asm mov ax,0x4c00),在编译后都放在数据段中,而C语言的数据声明语句仍按C的规则!
2.所有在main()函内的汇编语言的语句在编译后都放在代码段中,包括这个句子:
asm string2 db "the string can be declared after the main() function!$"
3.不要在以asm 开头的语句中使用C语言的关键字,这会导致编译阶段的错误

那么,根据这三条大家会得到什么样的结论呢?(先闭上眼想一想,你可能会由此变的
很赞赏自己,是的你应该这样相信自己是对的!)
让我们一起看一下这个结论:
1.根据编译原则1得到:不可以在main()外面写汇编命令语句(不要笑,正是与C语言相同才值得注意!),在任何地方都不要进行任何的段定义和宏定义(这是因为编译后的形式决定的,也即:在TC20下所有的汇编格式的语句只能是,直接性的数据定义和语句指令)!
2根据编译原则2得到:不可以在main()之内使用汇编的语句进行数据定义(同样不要笑,
大多数人在第一次在TC20下写汇编都会有这样的错误的)
3.如同类强制类型这样的事是不可以在以asm开头的汇编语句中使用的
好了,天即朗,气瞬清!这样一说,一个大体的框架就出来了!只要遵守这个原则写,就可避免很多莫名其妙的错误出现!
通俗的说:
汇编语句的数据定义放在main()外面,指令放在main()里面.
如果你没有更好的文档,那么记住我的这些话!

一些细节的问题:
在以asm开头的内联汇编语句中是不支持C的转义字符的,但是用C语言声明一个字符数组(含有转义字符的),然后用int 33 ah=9这功能时输出这个字符串时,其中的转义字符是有效的(这主要是因为编译后其内部表示形式不同造成的,自己想想会有答案的).
内联汇编支持C的一些如数值表示,字符串声明格式等,
如:一个十六进制的数据可以用两种方式表示:0xa 和0ah,字符串可以是这样:
"Hello,world!$"(如同C)也可以这样'Hello,world!$'(用汇编自己的方式).
象C一样你同样要注意赋值的类型,而且要比C更严格(汇编从来不自己动手做
如同类型转换啊这样事),所以一切的事完全要你自己做好!而且你不要企图以C的形式
做这件事,如这样的格式 asm mov dx,(unsigned)a(a是一个这样的东西,
char a[ ]="hello,world!";),而且这样句子也会导致错误:asm mov dx,word ptr a(逻辑错误),不过这不是在编译时的错误,而是运行期的错误(具体的原因自己想一想,象word label这样的东西的运算作用和会导致的后果),你可以这样用一个句子做"中间人"如int i=(unsigned)a;asm mov dx,i(也千万不要用asm mov dx,(unsigned)a 这样的句子.但是,告诉大家一个好消息,你可以用指针指向一个字符串,然后你会惊讶你竟然可以这样:
char *p="hello,world";asm mov dx,p,然后用int 33 ah=9的功能输出这个字符串而不会有错误(这也表现出指针的特点,它是一个二字节的(TC20下)变量,含有的是一个地址,这与其指向的变量的类型是毫无关系的).
内汇汇编语句不支持->这个运算符.还有标号的问题,在最后的例子中你会年看到一些特别之处!

上面所说的只是很细小并微少的一些事(也是很常遇到的),尚有很多的细节要说,但由于本人时间有限不能一一列举,如C的结构在内联汇编的应用等大家可以按照其运行机理去想想一下用法;另外,由于这只是一件学习的事,所以还是大家自己学(找一下有关文档,当然现在已经没有什么比较完整的了),情况会好的多,我在对内联汇编的学习过程中领会到了不少的东西,例如编译原理方面的知识,以及如何做会使代码更高效,占空间最少等的方法.最后向大家推荐一种方法,在利用TCC的-S开关可以生成C源文件的汇编代码
(或许很多的人都用过)是很好的学习材料!祝大家学有所成!

Cstarter
02-11-17

/* 由于个人的时间和能力有限,难免有错误和不详细的地方,请大家见谅!
My Email:[email protected] [email protected] QQ:170594633 */
一些例子:
下面这个例子是对沈美明 温冬婵的
<<IBM-PC 汇编语言程序设计>>清华版第十一章程序的改写
可直接在命令行上键入 tcc filename 就可以,当然你要有TASM.EXE
/*
asm mus_frep dw 330,294,262,294,3 p(330)
asm dw 3 p(294),330,392,392
asm dw 330,294,262,294,4 p(330)
asm dw 294,294,330,294,262,-1
asm mus_time dw 6 p(25),50
asm dw 2 p (25,25,50)
asm dw 12 p(25),100
*/
asm mus_frep dw 330,392,330,294,330,392,330,294,330
asm dw 330,392,330,294,262,294,330,392,294
asm dw 262,262,220,196,196,220,262,294,330,262
asm dw -1
asm mus_time dw 3 p (50),25,25,50,25,25,100
asm dw 2 p (50,50,25,25),100
asm dw 3 p (50,25,25),100

main()
{
asm jmp start
/*设置发声的频率,这一段在沈美明 温冬婵的
<<IBM-PC 汇编语言程序设计>>清华版第十一章有详细的说明 */

sound:
asm mov al,0b6h
asm out 43h,al
asm mov dx,12h
asm mov ax,533h*896
asm div di
asm out 42h, al
asm mov al,ah
/* 这个延时是用来防止两次IO操作的最后一次操作的错误,
因为CPU比总线的速度快很多,所以 要延时等待第一次操作完成后再进行第二次操作*/

asm mov cx,1000
delay:
asm loop delay

asm out 42h,al
asm in al,61h
asm mov ah,al
asm or al,3
asm out 61h,al

/* 使用中断15H功能86H延时CX:DX=微秒数*/
asm mov ax,2710h
asm mul bx
asm mov cx,dx
asm mov dx,ax
asm mov ah,86h
asm int 15h /*可用__int__(0x15);代替*/

asm mov al,ah
asm out 61h,al
asm jmp add_count
/*------------------*/
start:
asm mov si,offset mus_frep
asm lea bp,mus_time
frep:
asm mov di,[si]
asm cmp di,-1
asm je end_mus
asm mov bx,[bp]
asm jmp sound
add_count: /*标号不能用汇编语言写*/
asm add si,2
asm add bp,2
asm jmp frep
end_mus:;

}

对于上面的程序大家可用伪寄存器的方法写一个,要容易的多!

/*一个发声程序!(引自<<PC技术内幕>>电力版--这个版不好,不如清华版的)*/
#include"dos.h"
main()
{
static union REGS ourregs;
outportb(0x43,0xb6);
outportb(0x42,0xee);
outportb(0x42,0);
outportb(0x61,(inportb(0x61)|0x03));
ourregs.h.ah=0x86;
ourregs.x.cx=0x001e;
ourregs.x.dx=0x8480;
int86(0x15,&ourregs,&ourregs);
outportb(0x61,(inportb(0x61)&0xfc));
}

2. 在16位IBM—PC机i上使用C语言,若有一下定义

int i 4B
char ch 1B--字节对齐占用2B
double f 4B,所以b的内存是10B

3. C语言中的条件编译 #if define(宏名称)为什么错误了

预编译指令格式错误。
#if define (IBMPC)应改为#ifdef IBMPC
这种结构是为了防止头文件嵌套包含。一般的用法是
#ifndef _IBMPC_H
#define _IBMPC_H
#include"ibmpc.h"
....
#endif

4. 读过《IBM-PC汇编语言程序设计》的高手请进!

现在,笔记本里面,还有没有 8253,这都是个问题。
超过286的,就寥寥无几了,486以上,就没有了。

这样的书,没有几个人买。
属于行业机密,也不公开。

5. 在16位IBM-PC机上使用C语言,若有如下定义

1.所谓的16位32位64位系统是由cpu决定的,由机器指令的寻址、寄存器位数决定的。 os受cpu的限制,但在32位的cpu下16位的os也可以跑。很多os是向前兼容的,就是使以前的程序也能运行,如果编译器本身是16位,那么os会提供一个模拟16位的子环境供这个编译器使用 。

2.在32位系统中int占4个字节,32位,16位系统中占2个字节,16位。占多少位是根据系统来定的,一个字节固定是8位。16位系统中short的长度是2个字节,int的长度也是2个字节,所以范围长度为2^16为6 5 5 3 5,由于int是有符号的,所以取值范围为(-32768~32767),而无符号的short的取值范围则为(0~6 5 5 3 5),最大值为6 5 5 3 5,所以在16位系统中无符号short的值是有可能比int大。

6. C语言的主要特点是什么

  1. 有大量的算术和逻辑运算符,如+ , += , ++(自增),--(自减), & 等。

  2. 声明 语法模拟使用环境。 C有没有“定义”关键字,而不是被当作一个声明,声明类型的名称开始。 没有“function”这样的关键字,而是一个函数的参数列表的括号表示。

  3. 枚举类型中enum是关键字。没有标签并自由地相互转换的整数。

  4. C语言一共只有32个关键字,9种控制语句,程序书写自由,主要用小写字母表示。它把高级语言的基本结构和语句与低级语言的实用性结合起来。 C 语言可以象汇编语言一样对位、字节和地址进行操作, 而这三者是计算机最基本的工作单元。

  5. 结构式语言的显着特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰, 便于使用、维护以及调试。C语言是以函数形式提供给用户的,这些函数可方便的调用,并具有多种循环、条件语句控制程序流向,从而使程序完全结构化。

7. 关于c语言的,为什么在编程中涉及到显式使用IBM PC上的内存地址时,需要用long类型来存储呢,

你说应该是32位计算机系统,而内存地址则需要32位数据类型表示。
而long类型刚好是32位整型。

8. C语言题目。这题是选C吗,那D项为什么是对的求D项的详细解析,D项是IBM-PC,不是IBM_PC

C是错误的。预处理是在编译过程中的早期进行的;要是等执行再预处理那黄花菜都凉了……
D是正确的。'-'属于字符串可用的非转义字符。

9. IBM-PC汇编语言程序设计的目录

第一部分 汇编语言程序设计的基础知识
第1章 数据格式及其转换
第2章 8086CPU中寄存器的结构及使用
第3章 存储器的分段
第4章 数据和指令的寻址方式
第5章 80X86的指令系统
第6章 汇编语言程序格式及伪指令
第7章 汇编语言程序设计上机实践
第二部分 汇编语言程序设计的基本原理
第8章 顺序结构程序设计
第9章 分支结构程序设计
第10章 循环结构程序设计
第11章 子程序结构程序设计
第12章 输入、输出和中断程序设计
第13章 高级宏汇编语言技术
第14章 BIOS及DOS中断
附录
参考文献
……
作者: 沈美明,温冬婵 编着
出 版 社: 清华大学出版社
出版时间: 2001-8-1 字数: 711000 版次: 2 页数: 482 印刷时间: 2005-10-1 开本: 印次: 纸张: 胶版纸 I S B N : 9787302046646 本书主要阐述80X86汇编语言程序设计方法和技术。全书共分四部分:第1章和第2章为基础知识部分;第3章和第4章为编程工具部分,主要内容为80X86的指令系统与寻址方式,以及包括伪操作在内的汇编语言程序格式;第5章-第9章说明编程方法,内容包括循环、分支、子程序等基本程序结构,程序设计的基本方法和技术,多模块连接技术,宏汇编技术,以中断为主的输入输出程序设计方法,以及BIOS和DOS系统功能调用;第10章和第11章为实际应用部分,说明图形显示、发声和磁盘文件存取技术。全书提供了大量程序实例,每章后均附有习题。
本书在是1991年第1版的基础上,融会了10年来教学与科研的新成果改编成的。其第1版曾先后获得过原电子工业部工科电子类专业优秀教材一等奖、教育部科技进步一等奖、国家科技进步三等奖等;受到广大读者的欢迎,累计发行达130多万册。
本书适用于高等院校以及大、中专院校作为“汇编语言程序设计”课程的教材,本书也适于初学者使用,只要具有一种高级语言程序设计基础的读者,都可通过学习本书掌握汇编语言程序设计技术。 沈美明,女,江苏吴县人。1959年毕业于清华大学自动控制系计算机专业并留校任教至今。现为清华大学计算机系教授、博士生导师。
沈美明教授多年来一直从事并行处理/分布计算机系统、并行程序开发环境等方面的研究工作。近几年来,参加或负责的“高性能可扩展机群结构并行计算机系统”、“智能软件开发环境”等项目的研究成果达到了国际先进水平及国内领先水平,多次获得电子部及国家教委科技进步奖励。任本科生重要专业课“IBM-PC汇编语言程序设计”主讲教员,所编相应教材分别获国家级科技进步三等奖、电子部工科电子类专业优秀教材一等奖并成为行销全国的畅销书。几年来在国内外学术刊物及国际学术会议上发表论文近百篇。着作及译作有《计算机结构与并行处理》、《高等计算机系统结构》等。 再版前言
第1章 基础知识
1.1 进位记数制与不同基数的数之间的转换
1.2 二进制数和十六进制数运算
1.3 计算机中数和字符的表示
1.4 几种基本的逻辑运算
习题
第2章 80x86计算机组织
2.1 80x86微处理器
2.2 基于微处理器的计算机系统构成
2.3 中央处理机
2.4 存储器
2.5 外部设备
习题
第3章 80x86的指令系统和寻址方式
3.1 80x86的寻址方式
3.2 程序占有的空间和执行时间
3.3 80x86的指令系统
习题
第4章 汇编语言程序格式
4.1 汇编程序功能
4.2 伪操作
4.3 汇编语言程序格式
4.4 汇编语言程序的上机过程
习题
第5章 循环与分支程序设计
5.1 循环程序设计
5.2 分支程序设计
5.3 如何在实模式下发挥80386及其后继机型的优势
习题
第6章 子程序结构
6.1 子程序的设计方法
6.2 子程序的嵌套
6.3 子程序举例
习题
第7章 高级汇编语言技术
7.1 宏汇编
7.2 重复汇编
7.3 条件汇编
习题
第8章 输入输出程序设计
第9章 BIOS和DOS中断
第10章 图形与发音系统的程序设计
第11章 磁盘文件存取技术
附录
参考文献

10. IBM-PC汇编语言程序设计练习题

先做前两个大题吧
一:填空
1. AX又被称为(累加)器。

2. PF=1表示(低八位1的个数)为偶数。

3. 操作数直接存放在指令中,紧跟在操作码之后,他作为指令的一部分存放在代码段里,这种操作数称为(立即数)。

4. 62A0H+9D60H=(10000)H

5. 标号和变量都有三种属性:(1、段属性 2、偏移属性 3、类型属性)。

6. 在另一个模块中定义而要在本模块中使用的符号必须使用(段寻址)伪操作。(这题不肯定)

7. 逻辑运算是按(位)操作。

8. 循环程序通常由(初始化、循环工作与控制、循环结束的处理部分)三部分构成。

9. 129=(100000001)B

10. 机器数为88H,带符号十进制数(-120) 解题过程:88H即10001000B 第一个1表示是负数,而机器中的数都是以补码表示,补码又是原码变反加一,倒推一下,所以对应的正数是01111000,即120,所以~~

11. 将高级语言源程序翻译成机器语言程序的系统程序是(目标程序)。

12. (BP)称为基址指针寄存器。

13. 标识运算结果正负的标志是SF。SF=(1)时结果为正。

14. 8086实模式下一个段的大小可达(64K)B

15. 8086中可用于寄存器间接寻址的四个寄存器是(SP、BP、SI、DI)。

16. 在移位指令中,若移位次数大于1,就可将移位次数置于(CL寄存器)中。

17. 宏由(MACRO、ENDM)这一对伪指令来定义。

18. 访问堆栈的指令(如PUSH)只能使用(SS--堆栈段)作为段寄存器。

19. 指令CLD用于清除方向标志而(STD)指令使方向标志置1。

二。简答
根据以下要求,分别写出相应的汇编语言指令或指令序列。
1.把AX寄存器和BX寄存器的内容相减,结果存入AX中。
SBB AX,BX
2.将AX的内容逻辑左移5位。
MOV CL,5
SHL CL
3.将AX的内容,减去0520H和上次运算的借位。
SBB AX,0520H
4.将变量名TABLE的段地址送AX。
MOV AX,SEG TABLE
5.将DI的高四位置为0。
AND DI,0FH
6.输出一个字节到61H号端口。
OUT 61H,AL
7.将SI和DI的内容互换。
XCHG SI,DI