c语言和汇编语言混合编程(c语言和汇编语言混合编程,键盘输入4个十进制数,用汇编语言计算这四)

本文目录
- c语言和汇编语言混合编程,键盘输入4个十进制数,用汇编语言计算这四
- 汇编语言与c语言的合并编程怎么做
- 在C语言和汇编语言混合编程时,C程序与汇编程序将通过寄存器或堆栈来传递数据请写出
- 能不能把C语言和汇编语言一起用
- 如何C语言与汇编混编
- 怎么实现c语言与汇编语言的混合编程
- 用keil软体如何将汇编与C语言结合起来一起编写微控制器的程式
- ,C语言和汇编语言混合编程,键盘输入 4个数十进制数, 用汇编语言计算这4个数的均
c语言和汇编语言混合编程,键盘输入4个十进制数,用汇编语言计算这四
code segment
assume cs:code
org 100h
start:
push cs
pop ds
push cs
pop es
call inputnum
mov cx,num
mov ax,0
lea si,array
@1:
add ax,
inc si
inc si
loop @1
mov bx,num
div BL
xor ah,ah
call dispnum
mov ah,4ch
int 21h
; 键盘输入数值数组子程序(数组名为array,元素个数存放在num中)
inputnum proc near
; 输入的数据以一个空格分隔,以回车符结束输入
lea di,array ;将数组第一个元素的有效地址置入DI
mov word ptr,0
stin:
mov ax,0
push ax
again1:
mov ah,1
int 21h
mov byte ptr,al
cmp al,13
je line0
cmp al,’ ’
je line0
sub al,30h
mov ah,0
mov si,ax
pop ax
mov cl,10
mov ch,0
mul cx
add ax,si
push ax
jmp again1
line0:
pop ax
mov word ptr,ax
inc word ptr
cmp byte ptr,13
je stinend
inc di
inc di
jmp stin
stinend:
ret
array dw 100 dup(0)
num dw 0
char db ?
inputnum endp
; 显示十进制整型数值子程序
dispnum proc near
; 将要显示的数据放入AX中
mov dx,0
mov bx,10
div bx
mov byte ptr,dl ;保存个位
mov dx,0
div bx
mov byte ptr,dl ;保存十位
mov dx,0
div bx
mov byte ptr,dl ;保存百位
mov dx,0
div bx
mov byte ptr,dl ;保存千位
mov byte ptr,al ;保存万位
mov al,byte ptr
add al,30h ;万位转ASC2
mov byte ptr,al
mov al,byte ptr
add al,30h ;千位转ASC2
mov byte ptr,al
mov al,byte ptr
add al,30h ;百位转ASC2
mov byte ptr,al
mov al,byte ptr
add al,30h ;十位转ASC2
mov byte ptr,al
mov al,byte ptr
add al,30h ;个位转ASC2
mov byte ptr,al
mov di,1
disp1:
inc di
cmp di,6
je dispexit
cmp byte ptr,’0’
jne dispexit
mov byte ptr,’ ’
jmp disp1
dispexit:
mov ah,9
lea dx,y
int 21h
ret
y db 10,13,0,0,0,0,0,’$’
dispnum endp
codeends
end start
请在未来汇编环境中调试运行。
汇编语言与c语言的合并编程怎么做
通常国外都是这样做的. 写嵌入式程序都是 C/C++/C# 和ASSEMBLY language在一起的. 因为高级语言有比较全面的wrapping class. 做法: 1.用ASSEMBLY L写比较直白的, 能加快运行速度的东西, 比如两进制的右推和左推, 常常比高级语言要巧妙得多. 既然你提到这个问题, 你一定知道哪些用C, 哪些用ASSEMBLY L. 2.把C和ASSEMBLY的COMPILER加载到UNIX 或 LINUX, 用其下的 VI 或 EMACS 来写(这种方式主要是很方便),写的时候ASSEMBLY 和 C 的代码要分开, 各自成文 3.用Makefile来compile, 如果你不知道Makefile怎么写, 那就上网去找个例子, 照本宣科, 除了把所有的文件名换成你自己的. 4. 每次只要用make XXX就可以全部compile, 用make clean就可以全部清掉你所定义的所有.class .object .YY(随便你自己的需要了) XXX代表你的可执行文件的名字.
在C语言和汇编语言混合编程时,C程序与汇编程序将通过寄存器或堆栈来传递数据请写出
1. C语言中嵌入汇编
1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:
#pragma ASM
; Assembler Code Here
#pragma ENDASM
2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”
和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;
3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最后文件;
4、编译,即可生成目标代码。
来个实例吧:
#i nclude 《reg51.h》
void main(void)
{
P2=1;
#pragma asm
MOV R7,#10
DEL:MOV R6,#20
DJNZ R6,$
DJNZ R7,DEL
#pragma endasm
P2=0;
}
能不能把C语言和汇编语言一起用
当然可以啦,C和汇编有两种用法:
一是嵌入使用,如在C里嵌入汇编.
二是混合使用,C调用汇编过程或汇编调用C函数可以,需要编译器支持vc就可以,在保护模式的操作系统上如windowsxp 2000等,直接嵌入调用某些中断可能会被禁止,系统会报错返回。
如何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:wxe85@sina.com Cstarter1985@hotmail.com QQ:170594633 */
一些例子:
下面这个例子是对沈美明 温冬婵的
《《IBM-PC 汇编语言程序设计》》清华版第十一章程序的改写
可直接在命令行上键入 tcc filename 就可以,当然你要有TASM.EXE
/*
asm mus_frep dw 330,294,262,294,3 dup(330)
asm dw 3 dup(294),330,392,392
asm dw 330,294,262,294,4 dup(330)
asm dw 294,294,330,294,262,-1
asm mus_time dw 6 dup(25),50
asm dw 2 dup (25,25,50)
asm dw 12 dup(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 dup (50),25,25,50,25,25,100
asm dw 2 dup (50,50,25,25),100
asm dw 3 dup (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,
asm cmp di,-1
asm je end_mus
asm mov bx,
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));
}
怎么实现c语言与汇编语言的混合编程
这个问题有很多做法。如果你的汇编语句比较简单可以采用楼上的做法。
如果的你的汇编比较大,可以写成另外一个汇编文件*.asm。然后根据你的编译器给你的指令,把你的汇编函数抽象出C语言声明。做成*.h文件,供其他人调用。这是现在比较流行的底层API开发模式。
如 我把需要用汇编语句写的功能写一个汇编文件 asm_main.asm,我在该文件的前面 加一句 XDEF asm_main(这是我的编译器的规定,用XDEF),然后在asm_main.h里声明(就是典型的C声明 如 U16 asm_main())。这样你在你的C程序中如果用到汇编功能,只要#include "asm_main.h" 就可以调用用汇编写的函数了。对于大规模的软件开发,这是个很重要的方法。它提供了二次接口供上层调用。你可以把所有硬件驱动或底层API都写成这样子。C语言开发者就不需要了解底层硬件细节了。而且底层汇编的改动也不会影响C。这样你开发的C程序可移植性就高了。当然,你还需要些编译原理的知识。如,在汇编里,asm_main函数只是个标号,写成asm_main: 对吧,但是如果你需要些入口参数怎么办?比如你要抽象出U16 asm_main(char ,char *),这个时候你要考虑参数是怎样入栈的,一般是从右到左依次压栈的,等等还有些问题。
现在的大学本科教育只教一些单片机开发的小技能,没有一个系统的概念。我很愿意把我工作中得来的经验与大家分享。
用keil软体如何将汇编与C语言结合起来一起编写微控制器的程式
用keil软体如何将汇编与C语言结合起来一起编写微控制器的程式
在混合程式设计中,最常用也是最实用的方法是在C语言中加入部分组合语言的程式码,分为两种方法。
方法1)在Keil C51的函式中直接插入汇编语句
方法2)按照Keil C51介面规则,编写汇编模组
方法1是利用编译控制命令#pragma a *** (用来标识所插入的汇编语句的起始位置) 和 #pragma enda *** (用来标识所插入的汇编语句的结束位置) ,这两条命令必须成对出现,并可以多次出现。在Keil C51中不对插入的汇编程式码做任何的处理。
方法2编写汇编模组,需对KEIL编译器的编译过程做些了解。Keil编译器的编译过程是首先将专案中的一个个原始档编译为目的码(obj档案),然在再通过联结器产生为最终可执行的hex档案。
目的码将其中的程式码、资料、常量放在不同的“段”中,储存程式的段称为“程式码段”,储存资料的段称为“资料段”,最终目的码经过Keil的联结器按照“段”的要求转换为程式和资料地址固定的可执行档案。
在Keil软体中,“段”按定位属性分为:“可重定位段”和“绝对段”。
“可重定位段”:程式和资料在其分别所对应的储存单元(FLASH和RAM)中的储存地址是浮动的、可重定义的、相对可变的。
“绝对段”:其地址在连线前就已确定不变,联结器据此为它分配地址。
经Keil编译器生成的“段”具有如下属性:
1)段的储存属性(program code data pdata xdata bdata bit等);
2)段的起始地址;3)段的长度;
4)段的定位要求:绝对段地址固定,可重定位段定位的要求如要求程式码段在2K范围内,资料段定位在可位定址区等;
5)段名:包括程式和资料(变数和常量)的段的储存属性及段所属的程式模组(档案)。程式码段: ?PR? funame?Filename
资料段如:?DT? funame?Filename; ?BI? funame?Filename
标准段名字首列表
段字首 储存型别 含义
?PR? Program 程式储存区的程式码
?CO? code 程式储存区的常量
?BI? Bit 内部资料储存区的可位定址的位变数
?BA? Bdata 内部资料储存区的可位定址的位元组变数
?DT? Data 内部资料储存区的变数
?ID? Idata 内部资料储存区可间接定址的变数
?PD? Pdata 外部资料储存区的页变数
?XD? Xdata 外部资料储存区的变数
如何将微控制器的组合语言转成微控制器的c语言
只有自己重新编写
写stc微控制器的程式,用汇编语言用什么软体来程式设计呢
51微控制器系列一般都用KEIL程式设计 汇编 C语言都可以
在keil-c51中如何将汇编程式载入微控制器
我来回答,首先生成(.害克思)档案,然后各家微控制器载入方法都不一样,初学者以stc微控制器载入最简单,慢慢学,在以后就明白了为什么它载入简单,可买尽量支援微控制器型号多得烧写器,美名曰程式设计器,stc基本不用,为什么不用,可能是stc耍了个小聪明,在里面加了点小程式,就可以串列埠下载拉,制作stc下载线很简单,网上一搜就知道,经济紧张用stc,方便又快捷
如何用c语言编写微控制器程式。
使用微控制器专用的编译器,比如AVR微控制器要用ICC for AVR、AVR Studio 等。然后在选项中选择微控制器型号,比如ATmega16、ATmega128。最后要查询微控制器所对应的库,也就是标头档案。包含对应的标头档案,标头档案中有定义好的微控制器的变数名和函式,写程式要用到,比如引脚可能定义为PORTA,这些要记住,不可以写其他的变数名。具体写程式,和普通的C程式没有什么区别。
基本与普通C语言差不多,只不过微控制器标头档案肯定是与各自微控制器相关了,不是一般C所多用的STDIO.H,像51,一般是
#include《reg51.h》
51微控制器的程式设计软体(Keil)用汇编语言程式设计,如何将它汇入到isis 中?
你是想模拟吗????只要生成hex档案,在proteus拖入的晶片点右键选择edit(一般第二个选项) 然后将hex得路径汇入,就可以模拟。。。生成hex档案的方法是在keil选项卡中的output中设定,hexcreate打勾。。。。。
如何用keil软体编写微控制器程式
Keil系列教程:
:blog.csdn./column/details/13472.
使用汇编语言编写微控制器程式
^_^,这个可以用两个红外对管来实现,进去的时候1,2依次得到低电平,暂存器加1;有人出来的时候2,1依次得到低电平,暂存器减1
当暂存器等于0的时候,灯灭,不等于0的时候灯亮
^_^
程式很简单
就是怕学生会故意捣鬼,要是有一个人背著另一个走出去,灯就不会灭了
^_^
微控制器如何用C语言以及组合语言写滤波程式?
滤波,关键问题是演算法,有了演算法剩下的就是coding了
说白了,汇编与C,程式结构是一样的,也就是C一句话汇编要几句语句而已
,C语言和汇编语言混合编程,键盘输入 4个数十进制数, 用汇编语言计算这4个数的均
DATA SEGMENT
STR1 DB ’INPUT A HEX NUM: $’
HEX DB 5 ;计划输入的字符个数(含回车符)
NNN DB 0 ;存放实际输入的字符个数
DB 5 DUP(?)
BIN DW ? ;输入数字的二进制形式的存放单元
ERR DB 0AH, 0DH, ’ ERROR !’
DB 0AH, 0DH, ’ I HAVE NO TIME TO PLAY WITH YOU ! $’
STR2 DB 13, 10, ’BINARY IS: $’
DATA ENDS
;--------------------------------------------
STACK SEGMENT PARA STACK ’STACK’
DB 100 DUP(?)
STACK ENDS
;--------------------------------------------
CODE SEGMENT
ASSUME CS:CODE, SS:STACK, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
MOV AX, STACK
MOV SS, AX
LEA DX, STR1 ;’INPUT A HEX NUM’
MOV AH, 9 ;显示字符串
INT 21H
LEA DX, HEX
MOV AH, 10 ;等着输入四位HEX数
INT 21H
;---------------------------------------
;下面进行转换
MOV BIN, 0 ;先把二进制数字单元清零
LEA SI, HEX + 2;取输入字符串的首地址
MOV CH, NNN ;取输入字符的个数,用来控制循环处理的次数
CONV:
MOV BL, ;取来一个字符
CMP BL, 0DH ;和回车符进行比较
JZ END0 ;是, 即结束
CMP BL, ’0’
JB ERROR ;小于’0’转移
CMP BL, ’F’
JA ERROR ;大于’F’转移
CMP BL, ’9’
JNA A2B ;不大于’9’, 就去变换
CMP BL, ’A’
JNB A2B ;不小于’A’, 就去变换
JMP ERROR ;其它符号都是错误
;---------------------------------------
A2B:
SUB BL, 30H ;ASC--》BIN
CMP BL, 10
JB A2B_END
SUB BL, 07H ;ASC--》BIN
A2B_END:
;---------------------------------------
MOV BH, 0 ;弄成16位数
PUSH CX
MOV AX, BIN ;把原来的数字乘以16
MOV CX, 16
MUL CX
ADD AX, BX ;加上新输入的
MOV BIN, AX ;存结果,这就是二进制数
INC SI
POP CX
DEC CH ;处理次数减一
JNZ CONV ;非零转移
;---------------------------------------
DISP:
LEA DX, STR2 ;’BINARY IS: $’
MOV AH, 9 ;显示字符串
INT 21H
;---------------------------------------
MOV AX, BIN ;取来数字
MOV CX, 16 ;显示16位数
DDDD:
MOV DL, ’0’ ;先计划显示0
TEST AX, 8000H ;测试最高位
JZ DDD1
INC DL ;非0就显示1
DDD1:
PUSH AX
MOV AH, 2 ;显示DL中的ASCII码
INT 21H
POP AX
SHL AX, 1 ;左移
LOOP DDDD ;CX-1,非零转移
JMP END0 ;16位显示完毕,转到结束
;---------------------------------------
ERROR:
LEA DX, ERR
MOV AH, 09H ;错误信息提示
INT 21H
;---------------------------------------
END0:
MOV DL, 10
MOV AH, 2 ;显示DL中的ASCII码
INT 21H
MOV DL, 13
MOV AH, 2 ;显示DL中的ASCII码
INT 21H
;---------------------------------------
MOV AX, BIN ;取来数字
CALL DISP_AX
MOV AH, 4CH ;返回DOS
INT 21H
;------------------------------
DISP_AX:
MOV BX, 10 ;10进制.
MOV CX, 5 ;5位.
ABC:
MOV DX, 0
DIV BX
PUSH DX ;保存余数
LOOP ABC
MOV CX, 5 ;显示5位.
ASD:
POP DX
CMP DL, 10
JB A48
ADD DL, 7
A48:
ADD DL, 48
MOV AH, 2
INT 21H ;输出.
LOOP ASD
RET
;------------------------------
CODE ENDS
;---------------------------------------
END START
;=============================================

更多文章:
kali上传文件到apache服务器(如何在macOS系统和KaliLinux系统之间共享文件)
2025年10月25日 23:30
c语言一维数组有几个数(c语言的一维数组中至少要有几个元素)
2025年11月27日 13:30
织梦岛隐藏要素(塞尔达传说织梦岛脸孔神殿迷宫怎么通关 脸孔神殿迷宫)
2025年9月18日 18:45
最新版android studio安装(如何安装android studio)
2025年9月24日 10:15
97的十六进制(97 98 换成八进制 如何换 如何将十进制转换成八进制或者十六进制 哪位大仙帮帮忙)
2026年4月5日 15:00
redis命令登录(软件Xshell连接Redis操作教程)
2026年6月6日 17:30
category nouns(the different lexical category in translation)
2026年1月9日 10:45
哈夫曼树编码不唯一那解码结果(如何解决哈夫曼树不唯一的问题)
2025年6月24日 02:45
关系数据库管理系统有哪些?(下面哪些属于关系型数据库管理系统())
2026年5月2日 12:15
insertrow(在Power Query中如何插入自定义行)
2025年10月10日 12:30
















