C语言与汇编语言互相调用

C语言与汇编语言互相调用
C语言与汇编语言互相调用

浅谈C程序中调用汇编模块的方法

C语言是目前非常流行的一种编程语言,除具有高级语言使用方便灵活、数据处理能力强、编程简单等优点外,还可实现汇编语言的大部分功能,如可直接对硬件进行操作、生成的目标代码质量较高且执行的速度较快等。所以在工程上对硬件处理速度要求不很高的情况下,基本可以用C代替汇编语言,编写接口电路的控制软件。但C也不能完全取代汇编语言,如在一些对速度要求很高的实时控制系统中,以及对硬件的特殊控制方面,C有时也不能完全很好胜任,还需要汇编语言来编写。因为汇编语言目标代码更精练,对硬件直接控制能力更强和执行速度更快,但汇编语言编程烦难、表达能力差也显而易见。比较好的解决办法是C与汇编语言混合编程,即用C编写软件的调度程序、用户界面以及速度要求不高的控制部分,而用汇编语言对速度敏感部分提供最高速度的处理模块,供C调用。这种方法提供了最佳的软件设计方案,做到了兼顾速度效率高和灵活方便。由于本人的毕业设计需要C 程序中调用汇编模块的方法来提高ARM定点指令的执行速度,故对这方面进行了学习。学习心得如下:

对于C和汇编语言的接口主要有两个问题需要解决。

一、调用者与被调用者的参数传递

这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,自动依次压入堆栈;将所有参数压入堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压入堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。例如一调用名为add汇编程序模块的主函数:main( ){...... add(dest,op1,op2,flages);......}。在此例中对主函数进行反汇编,主函数在调用add函数前自动组织的堆栈。

.

.

.

lea 0xfffffffe8(%ebp),%eax #flages数组的首地址入栈

push %eax

pushl 0xfffffff8(%ebp) #OP2入栈

pushl 0xfffffffc(%ebp) #OP1 入栈

pushl 0xfffffff0(%ebp) #dest地址入栈

call 0x80483f0 #调用add函数

.

.

执行完add调用语句后,栈内数据结果如图一所示。

进入汇编子程序后,为了能正确获取主调程序并存入堆栈中的数据,被调的汇编子程序先后要做如下一些工作:

1、保存esp的副本

进入汇编子程序后,子程序中免不了要有压栈和出栈的操作,故ESP时刻在变化。为了能用ESP访问堆栈中的参数,安全办法是一进入子程序后,先为ESP制副本,以后对传递参数的访问都用副本进行。一般可用EBP保存ESP,如:

push %ebp

mov %ebp,%esp

2、保留数据空间

如果汇编子程序中需要一些局部数据,可以简单地减小ESP的值,以便在栈空间中保留出一段存贮区,用于存放局部数据,该区域须在子程序结束后恢复。如下语句可以保留一个局部数据区:

push %ebp

mov %ebp ,%esp

subl space,%esp;设space=4

movl $0x0,%ebp

movl $0x0,-2(%ebp)

如上语句段中,space是局部数据的总字节数。在以后的应用中,由于ESP是变化的,而EBP是固定的,用负偏移量可以存取局部变量。上例利用EBP及偏移量,将两个字的局部数据初始化为0。

3、保留寄存器值

如果在被调子程序中用到ESI、EDI等其它寄存器,则应先把它们压入堆栈,以保留寄存器原值。例如,下例就是将ESI和EDI寄存器的值压栈:

pushl %ebp

movl %ebp ,%esp

subl $space ,%esp,

pushl %esi

pushl %edi

4、获取传递参数

作完了1~3步的操作后,结合上面C程序传送参数这一例子,现在栈结构如图二所示。

由此可见,EBP保留了ESP在参数传递完并将EBP压栈后的一个副本,利用EBP可以很方便地访问各参数。现假设各参数都是2字节的整数值,在小模式编译方式共占用2个字节。如果要将传递的参数op1、op2取出,并分别赋给ebx、ecx寄存器,可由下列语句完成这一功能:

movl 0x8(%ebp),%eax

movl 0xc(%ebp),%ecx

5、子程序返回值

当子程序的执行结果需要返回时,根据返回值的字长,C按如下约定接收返回值:1字节在AL 寄存器中;2字节在EAX寄存器中;4字节则高位部分在EDX中、低位部分在EAX 寄存器中。C可从这些寄存器中取出返回值。

6、退出汇编子程序

结束汇编子程序的步骤如下:

1)若ESS、EDS、ESI或EDI已被压栈,则需按保存它们的相反顺序弹出它们。

2)若在过程开始时分配了局部数据空间,则以指令mov %esp和%ebp 恢复%esp。

3)以指令pop %ebp 恢复%ebp ,该步是必须的。或者可以用leave语句来恢复%ebp 。它相当于movl %ebp, %esp; popl %ebp

4)最后以ret结束汇编程序。

二、说明和建立调用者与被调用者间的连系

为了建立调用与被调用模块间的连接关系,被调用的汇编程序应用global,说明其可被外部模块调用;而调用程序则应预先说明要引用的外部模块名。下面通过我的例子进行说明,该例是C调用add0的汇编子程序。程序清单如下:

/* add.c */

#include

extern void add(int *dest,int op1,int op2,short int*flages);

/*声明调用外部的汇编函数*/

int main(void){

int op1,op2,result;

int *dest=&result;

short int flages[4]={0,0,0,0};

printf("please enter two soure operater:");

scanf("%x%x",&op1,&op2);

add(dest,op1,op2,flages);/*调用add0函数*/

printf("The result of ADD is :%x\n flages N(negative) Z(zero) C(carry) V(overflow:%d,%d,%d,%d\n",*dest,flages[3],flages[2],flages[1],flages[0]);

return 0;

}

#add.s

.text

.align 2

.global add

.type add,function

#定义add为外部可调用的函数

add:

push %ebp #ebp寄存器内容压栈,保存add函数的上级调用函数的栈基地址

mov %esp,%ebp #esp值赋给ebp,设置add函数的栈基地址

mov 0x8(%ebp),%edx

mov 0x10(%ebp),%eax

add 0xc(%ebp),%eax

mov %eax,(%edx)

mov 0x14(%ebp),%eax

jo OF

C:

jc CF

S:

js SF

jz ZF

jmp out

OF:

movw $0x1,(%eax)

jmp C

CF:

movw $0x1,0x2(%eax)

jmp S

SF:

movw $0x1,0x6(%eax)

movw $0x0,0x4(%eax)

jmp out

ZF:

movw $0x1,0x4(%eax)

movw $0x0,0x6(%eax)

out:

leave #将ebp值赋给esp,pop先前栈内的上级函数栈的基地址给#ebp,恢复原栈基址

ret #add函数返回,回到上级的调用函数

其中.text 标志一个代码段的开始,这是A T&T的段格式;global add;\n

type add,function说明add是公用的,可以由外部其它单独编译模块调用。

将C源程序以文件名add.c存盘,汇编语言源程序以add.s 存盘;通过MAKE进行编译和连接连接代码如下:

all: myadd

myadd: adds.o addc.o

gcc –o myadd adds.o adc.o

adds.o: add.s

as –o adds.o add.s

addc.o: add.c

gcc –g –o addc.o add.c

由上可见,在C中调用汇编模块很方便。所以我们在实际软件开发中,可以采用混合编程的技术,从而尽可能利用各语言的优势。既满足实际问题的需要,又简化设计过程,达到事半功倍的效果

C语言与汇编语言互相调用

浅谈C程序中调用汇编模块的方法 C语言是目前非常流行的一种编程语言,除具有高级语言使用方便灵活、数据处理能力强、编程简单等优点外,还可实现汇编语言的大部分功能,如可直接对硬件进行操作、生成的目标代码质量较高且执行的速度较快等。所以在工程上对硬件处理速度要求不很高的情况下,基本可以用C代替汇编语言,编写接口电路的控制软件。但C也不能完全取代汇编语言,如在一些对速度要求很高的实时控制系统中,以及对硬件的特殊控制方面,C有时也不能完全很好胜任,还需要汇编语言来编写。因为汇编语言目标代码更精练,对硬件直接控制能力更强和执行速度更快,但汇编语言编程烦难、表达能力差也显而易见。比较好的解决办法是C与汇编语言混合编程,即用C编写软件的调度程序、用户界面以及速度要求不高的控制部分,而用汇编语言对速度敏感部分提供最高速度的处理模块,供C调用。这种方法提供了最佳的软件设计方案,做到了兼顾速度效率高和灵活方便。由于本人的毕业设计需要C 程序中调用汇编模块的方法来提高ARM定点指令的执行速度,故对这方面进行了学习。学习心得如下: 对于C和汇编语言的接口主要有两个问题需要解决。 一、调用者与被调用者的参数传递 这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,自动依次压入堆栈;将所有参数压入堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压入堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。例如一调用名为add汇编程序模块的主函数:main( ){...... add(dest,op1,op2,flages);......}。在此例中对主函数进行反汇编,主函数在调用add函数前自动组织的堆栈。 . . . lea 0xfffffffe8(%ebp),%eax #flages数组的首地址入栈 push %eax pushl 0xfffffff8(%ebp) #OP2入栈 pushl 0xfffffffc(%ebp) #OP1 入栈 pushl 0xfffffff0(%ebp) #dest地址入栈 call 0x80483f0 #调用add函数 . . 执行完add调用语句后,栈内数据结果如图一所示。 进入汇编子程序后,为了能正确获取主调程序并存入堆栈中的数据,被调的汇编子程序先后要做如下一些工作: 1、保存esp的副本 进入汇编子程序后,子程序中免不了要有压栈和出栈的操作,故ESP时刻在变化。为了能用ESP访问堆栈中的参数,安全办法是一进入子程序后,先为ESP制副本,以后对传递参数的访问都用副本进行。一般可用EBP保存ESP,如: push %ebp mov %ebp,%esp

嵌入式简单汇编程序实例

ARM实验报告 姓名:郭健傧学号:L2101898 1.实验目的 (1)了解ADS1.2集成开发环境及ARMulator软件仿真; (2)熟悉ARM的乘法指令和逻辑指令; (3)结合ARM处理器硬件特性,比较处理函数的特性; 2.实验设备 硬件:pc机一台; 软件:Windowsxp系统,ADS1.2集成开发环境; 3.实验内容 (1)建立一个新的工程; (2)建立一个汇编文件,并添加到工程; (3)根据所给的两个C语言函数编写相应的汇编程序,并比较一下代码中fact1和fact2两个函数的特性; 4.实验步骤 (1)启动ADS1.2IDE集成开发环境,使用ARM Executable Image 工程模块建立一个工程heiye。 (2)建立汇编源文件test.s,编写程序实验,并添加到工程heiye中。 (3)设置工程连接地址Ro Base为0x40000000,RWBase为0x40003000。设置调试入口地址Image entry point为0x40000000。 (4)编译链接工程,并启动AXD进行软件仿真调试。 5.编写程序如下: C程序源代码: int fact1(int limit) { int fact=1; for(i=1;i

汇编语言的过程调用与c语言的函数调用

姓名:孙贵森 学号: 汇编语言地过程调用,如果需要传递参数,一般有种方法,通过寄存器来“传递”,或是通过参数来传递.(还有将所有参数制成参数列表并压栈地传递方法,但较少用.)通过寄存器来“传递”,不是真正意义上地传递,其只不过是事先在几个有限地寄存器中设置相应地值后,再调用过程,过程再直接读取这些寄存器地内容.可想而知,此法犹如语言中地全局变量,极易感染.而如果通过参数来传递,又不得不面临手工维护堆栈框架( )地重担.堆栈框架动态地存放着参数、调用过程地返回地址、过程局部变量、过程内地压栈等内容,也是不好对付地.一般情况下,一个普通地过程可能如下编写:文档来自于网络搜索 , ..... 作为遵从调用约定()调用者,则需这样调用上述过程: ; ; ; , * ; 而如果遵从调用约定,则: , ...... , [ ] ; , [ ]; ...... * ; , , ; ...... , [ ]; , [ ]; , [ ; , [ ]; ...... , ; * ;

在被调用地过程内,分为种情况: . 无参数,也无局部变量 . 有参数 . 有局部变量 当无参数且无局部变量时,堆栈中只是保存语句地下一条语句地地址,可以很安全地返回.而当有参数,使用伪指令地接收参数地形式,则会自动生成正确地返回代码.而当有局部变量,使用伪指令来定义局部变量,也会自动地生成正确地返回代码.在将参数压栈时,仍需将其打包为位地,文档来自于网络搜索 ; , ; ; 另一选择是,将用作地变量声明为. ; ; 还有另一种方法,即,总是传递指针. ; (, ) , ; , , , , , [] , , [] 这种方法在保留了我们可以声明仅需地变量类型地同时,也确保位地方法正确压栈.语言中地每一个函数都是一个独立地代码块.一个函数地代码块是隐藏于函数内部地,不能被任何其它函数中地任何语句(除调用它地语句之外)所访问(例如,用语句跳转到另一个函数内部是不可能地).构成一个函数体地代码对程序地其它部分来说是隐蔽地,它既不能影响程序其它部分,也不受其它部分地影响.换言之,由于两个函数有不同地作用域,定义在

汇编语言例子

实验三: 1)题目:在内存中从ARRAY开始的连续三个字节单元存放着30H,40H,50H。编制程序将这三个连续的数据传送到内存TABLE开始的单元。 DATA SEGMENT ARRAY DB 30H,40H,50H 定义数据段 TABLE DB 3 DUP (?) DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV ES,AX LEA SI,ARRAY LEA DI,TABLE MOV CX,3 REP MOVSB JMP $ CODE ENDS END START (2)题目:把内存2000H和3000H字单元的内容相加,结果存入4000H单元。(不考虑溢出) DATA SEGMENT ORG 2000H DW 1234H ORG 3000H DW 5678H ORG 4000H DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AX,[2000H] ADD AX,[3000H] MOV [4000H],AX JMP $ CODE ENDS END START 实验四 1、数据传送指令和算术运算指令完成NUM1和NUM2相加,结果放入SUM中。

DATA SEGMENT NUM1 DW 0012H,0030H,0FC21H ; 数1 NUM2 DW 3E81H,44E9H,6D70H ; 数2 SUM D W 3 DUP(?) ; 结果单元 DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV CX,3 LEA SI,NUM1 LEA DI,NUM2 LEA AX,SUM HE: MOV BX,[SI] ADD BX,[DI] MOV [AX],BX INC SI INC DI INC AX LOOP HE MOV AH, 4CH ; 返回DOS INT 21H CODE ENDS END START 2、内存中自TABLE开始的七个单元连续存放着自然数0至6的立方值(称作立方表)。;任给一数X(0≤X≤6)在XX单元,查表求X的立方值,并把结果存入YY单元中。;提示用XLAT指令 DATA SEGMENT TABLE DB 0H,1H,2H,3H,4H,5H,6H XX DB 1 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX LEA BX,TABLE MOV AL,[XX] XLAT MOV DL,AL MOV AH,02H INT 21H JMP $

汇编语言编程规范

软件设计更多地是一种工程,而不是一种个人艺术。如果不统一编程规范,最终写出的程序,其可读性将较差,这不仅给代码的理解带来障碍,增加维护阶段的工作量,同时不规范的代码隐含错误的可能性也比较大。 分析表明,编码阶段产生的错误当中,语法错误大概占20%左右,而由于未严格检查软件逻辑导致的错误、函数(模块)之间接口错误及由于代码可理解度低导致优化维护阶段对代码的错误修改引起的错误则占了一半以上。 可见,提高软件质量必须降低编码阶段的错误率。如何有效降低编码阶段的错误呢?这需要制定详细的软件编程规范,并培训每一位程序员,最终的结果可以把编码阶段的错误降至10%左右,同时也降低了程序的测试费用,效果相当显著。 本文从代码的可维护性(可读性、可理解性、可修改性)、代码逻辑与效率、函数(模块)接口、可测试性四个方面阐述了软件编程规范,规范分成规则和建议两种,其中规则部分为强制执行项目,而建议部分则不作强制,可根据习惯取舍。 1.排版 规则1 程序块使用缩进方式,函数和标号使用空格缩进,程序段混合使用TAB和空格缩进。缩进的目的是使程序结构清晰,便于阅读和理解。 默认宽度应为8个空格,由于Word中为4个空格,为示范清晰,此处用2个代替(下同)。 例如: MOV R1, #00H MOV R2, #00H MOV PMR, #PMRNORMAL MOV DPS, #FLAGDPTR MOV DPTR, #ADDREEPROM read1kloop: read1kpage: INC R1

MOVX A, @DPTR MOV SBUF, A JNB TI, $ CLR TI INC DPTR CJNE R1, #20H, read1kpage INC R2 MOV R1, #00H CPL WDI CJNE R2, #20H, read1kloop ;END OF EEPROM 规则2 在指令的操作数之间的,使用空格进行间隔,采用这种松散方式编写代码的目的是使代码更加清晰。 例如: CJNE R2, #20H, read1kloop ;END OF EEPROM 规则3 一行最多写一条语句。 规则4 变量定义时,保持对齐。便于阅读和检查内存的使用情况。 例如: RegLEDLOSS EQU 30H ; VARIABLE ; TESTLED==RegLEDLOSS.0 RegLEDRA EQU 31H ; VARIABLE

arm汇编语言调用C函数之参数传递

arm汇编语言调用C函数之参数传递 于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS 主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,关于ATPCS的详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回。 不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。 我们先讨论一下形参个数为4的情况. 实例1: test_asm_args.asm //-------------------------------------------------------------------------------- IMPORT test_c_args ;声明test_c_args函数 AREA TEST_ASM, CODE, READONLY EXPORT test_asm_args test_asm_args STR lr, [sp, #-4]! ;保存当前lr ldr r0,=0x10 ;参数 1 ldr r1,=0x20 ;参数 2

ldr r2,=0x30 ;参数 3 ldr r3,=0x40 ;参数 4 bl test_c_args ;调用C函数 LDR pc, [sp], #4 ;将lr装进pc(返回main函数) END test_c_args.c //-------------------------------------------------------------------------------- void test_c_args(int a,int b,int c,int d) { printk("test_c_args:\n"); printk("%0x %0x %0x %0x\n",a,b,c,d); } main.c //-------------------------------------------------------------------------------- int main() { test_asm_args(); for(;;); } 程序从main函数开始执行,main调用了test_asm_args,test_asm_args 调用了test_c_args,最后从test_asm_args返回main。代码分别使用了

汇编教程汇编语言编程实例

汇编语言编程实例一这一章,我们要把我们已学的知识集合起来。具体来讲,我们来写一个使用ODBC APIs的程序.为简单起见,这个程序中我使用Microsoft的Access数据库(Microso ft Access 97) . 注意:如果你使用的windows.inc 是1.18及其以下版本,在开始编译之前要修改其中的一个小bug.在windows.inc中查找 "SQL_NULL_HANDLE",将得到下面这行: SQL_NULL_HANDLE equ 0L 将0后面的"L"删除,象这样: SQL_NULL_HANDLE equ 0 这个程序是一个基于对话框的程序,有一个简单的菜单.当用户选择"connect"时,它将试图连接test.mdb数据库,如果连接成功,将显示由ODBC驱动程序返回的完整连接字符串.接下来,用户可选择"View All Records"命令,程序会使用listview control来显示数据库中的所有数据.用户还可以选择"Query"命令来查询特定的记录.例子程序将会显示一个小对话框提示用户输入想找的人名.当用户按下OK钮或回车键,程序将执行一个查询来查找符合条件的记录.当用户完成对数据库的操作时,可以选择"disconnect"命令与数据库断开连接. 现在看一下源程序: .386 .model flat,stdcall include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\odbc32.inc include \masm32\include\comctl32.inc include \masm32\include\user32.inc includelib \masm32\lib\odbc32.lib includelib \masm32\lib\comctl32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib IDD_MAINDLG equ 101 IDR_MAINMENU equ 102 IDC_DATALIST equ 1000 IDM_CONNECT equ 40001 IDM_DISCONNECT equ 40002 IDM_QUERY equ 40003 IDC_NAME equ 1000 IDC_OK equ 1001 IDC_CANCEL equ 1002 IDM_CUSTOMQUERY equ 40004 IDD_QUERYDLG equ 102 DlgProc proto hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

汇编语言程序实例

一:题目 编写求十进制数12678532与41412042(本人学号)之和的程序,并将和以十进制数的形式送屏幕显示。 二:要求 (1)两个加数均以压缩(组合)十进制数形式存放在ADD1和ADD2为首址的存贮器单元。 (2)和以压缩十进制数的形式存入SUM以下单元。 (3)将和送到屏幕显示部分功能的实现采用子程序的形式。三:算法设计 1:程序 DATAS SEGMENT ;此处输入数据段代码 ADD1 DD 12678532H ADD2 DD 41412042H SUM DD ? DATAS ENDS STACKS SEGMENT STACK 'STACK';此处输入堆栈段代码 DW 100H DUP(?) TOP LABEL WORD STACKS ENDS CODES SEGMENT

ASSUME CS:CODES,DS:DATAS,SS:STACKS START: MOV AX,DATAS MOV DS,AX MOV AX,STACKS MOV SS,AX ; LEA SP,TOP LEA SI,ADD1 LEA DI,ADD2 MOV AL,[SI] ADD AL,[DI] DAA MOV BYTE PTR SUM,AL MOV AL,[SI+1] ADC AL,[DI+1] DAA MOV BYTE PTR SUM+1,AL MOV AL,[SI+2] ADC AL,[DI+2] DAA MOV BYTE PTR SUM+2,AL

MOV AL,[SI+3] ADC AL,[DI+3] DAA MOV BYTE PTR SUM+3,AL MOV AX,WORD PTR SUM+2 CALL DISPAX MOV AX,WORD PTR SUM CALL DISPAX ; MOV AH,4CH INT 21H DISPAL PROC NEAR PUSH AX PUSH CX PUSH DX PUSH AX MOV CL,4 SHR AL,CL CALL CHANG MOV AH,02 MOV DL,AL

单片机基础汇编语言编程实例

单片机基础汇编语言编程实例 单片机汇编语言编程 1.编写程序,用位处理指令实现“P1.4=P1.0∨(P1.1∧P1.2)∨P1.3”的逻辑 功能。 MOV C,P1.1ANL C,P1.2ORL C,P1.0ORL C,P1.3MOV P1.3,C2.编写程序,若累加器A 的内容分别满足下列条件,则程序转到LABLE 存储单元。设A 中存 放的的无符号数。(1)A≥10;(2)A>10;(3)A≤10。(1)CJNE A,#10,NEXTLJMP LABLENEXT:JNC LABLE(2)CJNE A,#10,NEXTLJMP NEXT2NEXT:JNC LABLENEXT2:(3)CJNE A,#10,NEXTLJMP LABLENEXT:JC LABLE3.编写程序,查找片内RAM 的30H~50H 单元中是 否有55H 这一数据,若有,则51H 单元置为FFH;若未找到,则将51H 单元 清0。MOV R0,29HNEXT:INC R0CJNE R0,#51H,NEXT2MOV 51H,#0FFHAJMP OVERNEXT2:CJNE @R0,#55H,NEXTMOV 51H,#0OVER:4.编写程序,查找片内RAM 的30H~50H 单元中出现0 的次数,并将查找的结果存入51H 单元。MOV R0,30HMOV 51H,#0NEXT:CJNE @R0,#00H,NEXT2INC 51HNEXT2:INC R0CJNE R0,#51H,NEXT5.在片外RAM 中有一个数据块,存有若干字符、数字,首地址为SOURCE 要求将该数据块传送到片内RAM 以DIST 开始的区域,直到遇到字符“$”时结束($也要传送,它的ASCII 码为24H)。MOV DPTR,#SOURCEMOV R0,#DISTNEXT:MOVX A,@DPTRMOV @R0,AINC DPTRINC R0CINE A,#24H,NEXT6.片内RAM 的30H 和31H 单元中存放着一个16 位的二进制数,高位在前,低位在后。编写程序对其求补,并存回原处。CLR CMOV A,#0SUBB A,31HMOV 31H,AMOV A,#0SUBB A,30HMOV 30H,A7.片内RAM 中有两个4 字节压缩的BCD 码形式存放的十进制数,一

51汇编程序实例.

51汇编程序实例:举一例说明:流水灯加数码管LOOP: ; 标号 CLR P2.6 ;选中p2.6 数码管左边的8字使能SETB P2.7 ;p2.7不使能。右边的数码管消隐MOV P0,#28H ;把28h送p0口;数码管显示0 LCALL DELAY ;延时 MOV P0,#0FFH ;0ffh 送p0口,数码管清除CLR P1.0 ;点亮p1.0发光管 MOV P0,#7EH ;把7eh送p0口;数码管显示1 LCALL DELAY MOV P0,#0FFH CLR P1.1 ;点亮p1.0发光管 CLR P1.0 ;点亮p1.0发光管 MOV P0,#0A2H ;数码管显示2 LCALL DELAY MOV P0,#0FFH CLR P1.2 CLR P1.1 CLR P1.0 MOV P0,#62H ;数码管显示3 LCALL DELAY MOV P0,#0FFH CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 MOV P0,#74H ;数码管显示4 LCALL DELAY MOV P0,#0FFH CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 MOV P0,#61H ;数码管显示5; LCALL DELAY MOV P0,#0FFH CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 MOV P0,#21H ; 数码管显示6 LCALL DELAY MOV P0,#0FFH CLR P1.6 CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 MOV P0,#7AH ; 数码管显示7 LCALL DELAY MOV P0,#0FFH CLR P1.7 CLR P1.6 CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2

C语言调用汇编语言时变量的传递

F2812中C语言调用汇编函数 参考资料: (1) SPRU514 ---- TMS320F28x Optimizing C/C++ Compiler User’s Guide.pdf; (2) spru430d ---- TMS320C28x DSP CPU and Instruction Set Reference Guide; (3) spru513c ---- TMS320C28x Assembly Language Tools User's Guide. 一、编写C语言能调用的.asm文件 以delay.asm为例: 1、将文件保存为.asm文件; 2、在文件中编写如下代码: ;********************************************************** ***********/ ;* 鲍正华*/ ;* 2010.07.09 */

;********************************************************** ***********/ ;//######################################################### ################## ; @FunctionName: Delay_asm ; ; @Brief: 延时1s ; ; @Param: unsigned long cnt 传给ACC ; ; @Return: 无 ;//######################################################### ################## .def _Delay_asm .global _Delay_asm

24个汇编实例小程序

24个汇编小程序 题目列表: 逆序输出字符串“BASED ADDRESSING” 从键盘上输入两个数,分别放到x,y单元,求出它们的和 是编写一段程序,要求在长度为10h的数组中,找出大于42h的无符号数的个数并存入地址为up开始区域,找出小于42h的无符号数的个数并存入地址为down的开始区域 键盘输入一段字符串,其中小写字母以大写字母输出,其他字符不变输出 从键盘上就收一个小写字母,找出它的前导字符和后续字符,在顺序显示这三个字符 把一个包含20个数据的数组M分成两组:正整数组P和负整数组N,分别把这两个数组中的数据的个数显示出来 求出首地址为data的100个字数组中的最小偶数,并把它放在ax中 输入两船字符串string1和string2,并比较两个字符串是否相等,相等就显示“match”,否则显示“no match” 从键盘接收一个四位的十六进制数,并在终端显示与它等值的二进制数 从键盘输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,并显示计数结果 有一个首地址为mem的100个字的数组,试编程序删除数组中所有为零的项,并将后续项向前压缩,最后将数组的剩余部分补上零 从键盘上输入一串字符(用回车键结束,使用10号功能调用)放在string中,是编制一个程序测试字符串中是否存在数字。如有,则把cl的第五位置1,否则将该位置置0 在首地址为data的字数组中,存放了100h的16位字数据,试编写一个程序,求出平均值放在ax寄存器中,并求出数组中有多少个数小于此平均值,将结果放在bx寄存器中(f分别考虑有符号数、无符号数情况) 一直数组A包含15个互不相等的整数,数组B包含20个互不相等的整数。试编制一个程序,把既在A中又在B中出现的整数存放于数组C中 设在A、B和D单元中分别存放着三个数。若三个数都不是0,则求出三个数的和并存放在S单元,若其中有一个数为0,则把其它两个单元也清零。请编写此程序

汇编考前辅导带答案版

一、单项选择题 1、CPU发出的访问存储器的地址是(A )。 A.物理地址 B.偏移地址 C.逻辑地址 D.段地址 2、下列指令中操作数在代码段中的是(A )。 A.MOV AL,42H B.ADD AL,BL C.SUB [BX],DI D.INC [DI] 3、与MOV BX,OFFSET VAR指令完全等效的指令是(D )。 A.MOV BX,VAR B.LDS BX,VAR C.LES BX,VAR D.LEA BX,VAR 4、表示过程定义结束的伪指令是(A )。 A.ENDP B.ENDS C.END D.ENDM 5、BUF1 DB 3 DUP(0,2 DUP(1,2),3) COUNT EQU $ - BUF1 符号COUNT等价的值是(B )。 A.6 B.18 C.16 D.8 6、下列寄存器中,作为16位寄存器的是(D )。 A. AL B. BL C. CH D.DX 7、在程序运行过程中,确定下一条指令的物理地址的计算表达式是(C )。 A.DS*16+SI B. ES*16+DI C. CS*16+IP D. SS*16+SP 8、物理地址(10FF0H )=10H,(10FF1H )=20H,(10FF2H )=30H,从地址10FF1H中取一个字的内容是(B )。 A.1020H B.3020H C.2030H D.2010H

9、将AX 清零,下列指令错误的是(C )。 A.SUB AX,AX B.XOR AX,AX C.OR AX,00H D.AND AX,00H 10、完成同指令XCHG AX,BX相同功能的指令或指令序列是(D )。 A. MOV AX,BX B. MOV BX,AX C. PUSH AX D. MOV CX,AX POP BX MOV AX,BX MOV BX,CX 11、JMP BX 的目标地址的偏移量为(A )。 A. BX 的内容 B. BX 所指向的内存单元的内容 C. IP + BX 的内容 D. IP + [BX] 12、可用作寄存器间接寻址或基址、变址寻址的地址寄存器,正确的是(D )。 A.AX,BX,CX,DX B.DS,ES,CS,SS C.SP,BP,IP,BX D.SI,DI,BP,BX 13、设SP初值为2000H,执行指令“PUSH AX”后,SP的值是(D )。 A.1FFFH B.1998H C.2002H D.1FFEH 14、汇编语言源程序中,每个语句可由四项组成,其中名字项是一个符号,下面列出的有效名字是(A )。 A.Variable B.First&ld C.0FFFFH D.‘Memphis’ 15、要求将A,B两个字符的ASCⅡ码41H,42H顺序存放在连续两个字存储单元中,可选用的语句是(B )。 A.DA1DB‘AB’ B.DA1DW‘AB’ C.DA1DB0ABH D.DA1DW0ABH

数码管动态显示汇编程序例子

;数码管动态显示汇编程序例子,显示12(时)38(分) H10 EQU 65H H1 EQU 66H M10 EQU 67H M1 EQU 68H SHOUR EQU 69H SMIN EQU 6AH DISH10 EQU 6FH DISH1 EQU 70H DISM10 EQU 71H DISM1 EQU 72H MEMA EQU 75H MEMB EQU 79H ORG 0000H AJMP STAR ORG 0030H ;数码管数据表格 TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H DB 90H,88H,83H,0C6H,0A1H,86H,8EH ;0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F ORG 0050H STAR: MOV SHOUR,#12; 设为12时 MOV SMIN,#38; 设为38分 MOV MEMA,#0 MOV MEMB,#0 MOV SP,#30H MOV PSW,#00H ;############################# MAIN: MOV SP,#30H MOV PSW,#00H MOV MEMA,SHOUR MOV MEMB,SMIN ACALL TLED; 把要显示的数转换成数码管代码 ACALL DISPLAY; 显示小时,分钟 MOV P0,#0FFH MOV P1,#0FFH AJMP MAIN ;######################################### ; 显示小时,分钟 DISPLAY:MOV P0,DISH10 MOV P1,#11111110B ACALL D1MS MOV P0,DISH1 MOV P1,#11111101B

汇编语言小程序例子

1.编写统计AX中1、0个数的源程序。1的个数存入CH,0的个数存入CL。 CODE SEGMENT ASSUME CS:CODE START: MOV CX, 0 MOV DX,17 AA1: SUB DX, 1 JZ AA3 SHL AX, 1 JNC AA2 INC CH JMP AA1 AA2: INC CL JMP AA1 AA3: MOV AH,4CH INT 21H CODE ENDS END START 2.编写比较两个字符串STRING1和STRING2所含字符是否完全相同的源程序,若相同则显示“MATCH”,若不相同则显示“NO MATCH”。

程序: DATA SEGMENT R1 DB 'MATCH',0AH,0DH R2 DB 'NO MATCH',0AH,0DH STRING1 DB 'XXXXX' N1 EQU $-STRING1 STRING2 DB 'YYYYY' N2 EQU $-STRING2 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AX,N1 CMP AX,N2 JNZ AA1 ADD AX,1 LEA SI,STRING1 LEA DI,STRING2 AA2: MOV BL,[SI] MOV BH,[DI] INC SI

INC DI SUB AX,1 JZ AA3 CMP BL,BH JZ AA2 JMP AA1 AA3: LEA BX,R1 MOV CX,7 AA4: MOV DL,[BX] INC BX MOV AH,2 INT 21H LOOP AA4 JMP E AA1: LEA BX,R2 MOV CX,10 AA5: MOV DL,[BX] INC BX MOV AH,2 INT 21H LOOP AA5 E: MOV AH,4CH

汇编语言程序设计2008A,有答案

汇编语言程序设计2008A 一、单项选择题(本大题共20小题,每小题1分,共20分)在每小题列出的四个备选项中只有一个是符合题目要 求的,请将其代码填写在题后的括号内。错选、多选或未选均无分 1.在汇编语言源程序中,以下哪一个编码是二进制形式的编码() (A)1010 (B)01H (C)01000101B (D)22D 2.假设(AL)=34H,(AH)=2FH,执行指令XCHG AL, AH 后,(AH)为() (A)2FH (B)34H(C)00H (D)3FH 3.TF标志位的含义为() (A)单步标志(B)最高位进位标志(C)补码溢出标志(D)零值标志 4.对于指令MOV AL, [BX],其源操作数的寻址方式为() (A)寄存器寻址(B)立即数寻址(C)基址寻址(D)寄存器间接寻址 5.对于指令POP 0100H[BX][SI],其目的操作数的寻址方式为() (A)寄存器寻址(B)变址寻址(C)基址寻址(D)基址变址寻址 6.假设(BX)=0100H,对于指令ADD AL, 0200H[BX],其源操作数的有效地址为() (A)0100H (B)0200H (C)0300H (D)0400H 7.假设(DS)=0C00H,由逻辑地址0C00H:0200H所指示的字类型内存单元内容为02FDH,执行指令LEA BX, [0200H]后,(BX)为() (A)不确定(B)02FDH (C)0200H (D)0C00H 8.以下标志位中,INC指令不影响的标志位是() (A)CF (B)AF (C)OF (D)PF 9.假设(AL)=0F2H,执行指令ADD AL, 34H后,OF标志位的取值为() (A)1 (B)0 (C)2 (D)不确定 10.假设(BL)=01H,执行指令SUB BL, 02H后,CF标志位的取值为() (A)1 (B)0 (C)2 (D)3

汇编语言小程序例子

汇编语言小程序例子

1.编写统计AX中1、0个数的源程序。1的个数 存入CH,0的个数存入CL。 CODE SEGMENT ASSUME CS:CODE START: MOV CX, 0 MOV DX,17 AA1: SUB DX, 1 JZ AA3 SHL AX, 1 JNC AA2 INC CH JMP AA1 AA2: INC CL

JMP AA1 AA3: MOV AH,4CH INT 21H CODE ENDS END START 2.编写比较两个字符串STRING1和STRING2所 含字符是否完全相同的源程序,若相同则显示“MATCH”,若不相同则显示“NO MATCH”。 程序: DATA SEGMENT R1 DB 'MATCH',0AH,0DH

R2 DB 'NO MATCH',0AH,0DH STRING1 DB 'XXXXX' N1 EQU $-STRING1 STRING2 DB 'YYYYY' N2 EQU $-STRING2 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AX,N1 CMP AX,N2 JNZ AA1 ADD AX,1

LEA SI,STRING1 LEA DI,STRING2 AA2: MOV BL,[SI] MOV BH,[DI] INC SI INC DI SUB AX,1 JZ AA3 CMP BL,BH JZ AA2 JMP AA1 AA3: LEA BX,R1 MOV CX,7 AA4: MOV DL,[BX]

汇编程序实例素数输出

a d b ? b db ? d db 10 mes0 db 'Input the number:',0ah,0dh,'$' mes1 db 0ah,0dh,'the prime number small than the number of ','$' mes2 db 'is:',0ah,0dh,'$' data ends stack segment dw 100(?) stack ends code segment assume cs:code,ds:data mainproc far start: mov ax,data mov ds,ax lea dx,mes0 mov ah,9 int 21h mov a,0 shuru: mov ah,01h int 21h cmp al,0dh jz ok sub al,30h mov b,al mov al,a mul d add al,b mov a,al jmp shuru ok: lea dx,mes1 mov ah,9 int 21h mov bl,a call shuchu lea dx,mes2 mov ah,9 int 21h

xunhuan: call panduan inc bl cmp bl,a jng xunhuan mov ah,1 int 21h ret mainendp panduan proc near mov ah,0 mov al,bl mov b,2 jmp yunsuan yunsuan: cmp al,b jz shuchu0 div b cmp ah,0 jz shuchu1 inc b mov ah,0 mov al,bl jmp yunsuan shuchu0: call shuchu shuchu1: ret panduan endp shuchu proc near mov ah,0 mov al,bl mov cx,0 op: inc cx div d add ah,30h mov dl,ah mov dh,0

51单片机汇编语言及C语言经典实例

51单片机汇编语言及C语言经典实例 实验及课程设计

一、闪烁灯 如图1 所示为一简单单片机系统原理图:在P1.0 端口上接一个发光二极管L1,使L1 在不停地一亮一灭,一亮一灭的时间间隔为0.2 秒。 延时程序的设计方法,作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要 求的闪烁时间间隔为0.2 秒,相对于微秒来说,相差太大,所以我们在执行某一指令时, 插入延时程序,来达到我们的要求,但这样的 延时程 序是如何设计呢?下面具体介绍其原理:如图4.1.1 所示的石英晶体为12MHz,因此,1 个机器周期为 1 微秒,机器周期微秒如图 1 所示,当P1.0 端口输出高电平,即P1.0=1 时,根据发光二极管的单向导电性可知,这时发光 二极管L1 熄灭;当P1.0 端口输出低电平, 即P1.0=0 时,发光二极管L1 亮;我们可以使用SETB P1.0 指令使P1.0端口输出高电 平,使用CLR P1.0 指令使P1.0 端口输出低 电平。 C 语言源程序 #include sbit L1=P1^0; void delay02s(void) //延时0.2 秒子程序 { unsigned char i,j,k; for(i=20;i>0;i--) for(j=20;j>0;j--) for(k=248;k>0;k--); } void main(void) { while(1) { L1=0; delay02s(); L1=1; delay02s(); } 汇编源程序 ORG 0 START: CLR P1.0 LCALL DELAY SETB P1.0 LCALL DELAY LJMP START DELAY: MOV R5,#20 ;延时子程序,延时0.2 秒D1: MOV R6,#20 D2: MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET END 图2 程序设计流程图图1 单片机原理图

实验1 汇编语言 数据传送

实验1 数据传送 实验目的 掌握8086指令系统的数据传送指令及8086的寻址方式 利用调试工具来调试汇编语言程序 实验设备 PC微型计算机一台 实验预习要求: 复习8086指令系统的数据传送指令及8086的寻址方式 学习TD.EXE的使用方法 实验内容1: 通过下面的程序段输入和执行来熟悉TD.EXE的使用,通过显示屏观察程序的执行情况。练习程序段如下: MOV BL, 88H MOV CL, BL MOV AX, 9999H MOV DS:[0002H], AX 操作步骤: 1、启动TD.EXE 方法1 直接打开BIN文件夹下TD.EXE文件,方法2 把BIN 文件夹放在根目录下,如在:D:\BIN,打开“开始—附件—命令提示符”用CD命令使当前目录为D:\BIN 然后输入TD 或TD.EXE 2、输入程序段 把光标移到CS:0100H处开始输入程序 在光标处直接输入练习程序段,键入时屏幕上会弹出一个输入窗口,在这个窗口中输入程序段 3、执行程序段 按F8单步执行程序段,观察寄存器内容的变化情况和内存单元DS:[0002H]的内容变化情况 实验内容2: MOV AX, 1111H MOV BX, 2222H MOV CX, 3333H PUSH AX PUSH BX PUSH CX 第一种出栈方式 POP AX

POP BX POP CX 第二种出栈方式 POP BX POP CX POP AX 第三种出栈方式 POP CX POP BX POP AX 操作步骤: 1、启动TD.EXE 2、输入程序段 把光标移到CS:0100H处开始输入程序 在光标处直接输入练习程序段,键入时屏幕上会弹出一个输入窗口,在这个窗口中输入程序段 3、执行程序段 按F8单步执行程序段,观察寄存器内容的变化情况和内存单元DS:[0002H]的内容变化情况 实验报告要求: 1、写明本次实验的执行结果,填好表1-1 2、设置各寄存器及存储单元的内容如下 BX=0010H , SI=0001H DS:[0010H]=12H, DS:[0011H]=34H, DS:[0012H]=56H, DS:[0013H]=78H, DS:[0014H]=9AH, DS:[0015H]=0ABH, DS:[0016H]=0BCH 说明下列各条指令执行完后AX寄存器中的内容,上机验证(观察寄存器和TD数据区—在窗口的左下角)并填好表1-2(注:输入下列指令前应先用MOV指令把各寄存器和在存储单元的内容设置好) (1)MOV AX, 1200H (2)MOV AX, BX (3)MOV AX, [0010H] (4)MOV AX, [BX] (5)MOV AX, 0005H[BX] (6)MOV AX, [BX][SI] (7)MOV AX, 0003H[BX][SI]

相关文档
最新文档