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 %eaxpushl 0xfffffff8(%ebp) #OP2入栈pushl 0xfffffffc(%ebp) #OP1 入栈pushl 0xfffffff0(%ebp) #dest地址入栈call 0x80483f0 <add> #调用add函数..执行完add调用语句后,栈内数据结果如图一所示。
关于c语言和汇编语言相互嵌套调用的学习总结

关于c语言和汇编语言相互嵌套调用的学习总结在计算机编程中,C语言和汇编语言是两种常用的编程语言。
C语言是一种高级语言,而汇编语言则是一种低级语言。
尽管C语言在编程方面更为简单和人性化,但是汇编语言却更为底层和灵活。
因此,在一些特定的情况下,C语言与汇编语言会相互嵌套调用,以充分发挥各自的优势。
首先,理解C语言和汇编语言的基本特点是学习的关键。
C语言是一种结构化的高级语言,它具有变量和函数的特性。
C语言通过调用函数来完成特定的任务,使用变量来存储和操作数据。
相比之下,汇编语言是一种低级语言,它直接操作计算机硬件,使用寄存器和内存地址来存储和操作数据。
汇编语言的指令直接映射到底层的CPU指令。
其次,学习如何在C语言中嵌入汇编代码。
在C语言中,可以使用内联汇编语句来嵌入汇编代码。
为了实现这一点,需要使用特殊的语法。
在GCC编译器中,可以使用asm关键字来指定内联汇编代码。
内联汇编语句由汇编语句和C语言代码组成,以实现C函数内的底层操作。
通过内联汇编,可以直接访问底层硬件功能,并在C函数中实现特定的优化。
而在汇编语言中嵌入C代码则需要借助外部汇编调用接口。
在C语言中编写函数时,可以使用extern关键字声明函数为外部函数。
对于汇编语言而言,可以使用特定的语法和指令来调用C函数。
在调用C函数时,需要将参数传递给C函数,并处理返回值。
通过外部汇编调用接口,可以在汇编语言中利用C函数的高级功能,如数组操作、内存分配等。
当C语言和汇编语言相互嵌套调用时,需要注意以下几点。
首先,理解数据传递的原理。
C语言和汇编语言使用不同的参数传递方式。
C语言通常使用栈来传递参数,而汇编语言则使用寄存器。
在混合编程中,需要确保参数正确地传递给函数。
其次,需要注意变量的声明和使用。
C语言和汇编语言使用不同的编译规则和约定。
在混合编程中,需要正确地定义和使用变量,以免引起错误。
此外,需要注意寄存器的保存和恢复,以避免影响程序的正确执行。
Keil软件“C语言”与“汇编”混编——相关知识整理

Keil软件“C语言”与“汇编”混编相关知识整理用Keil在C中嵌入汇编 (1)在Keil中嵌入汇编 (2)介绍直接嵌入汇编代码的方法 (4)采用汇编可能会有的好处 (5)Keil C语言与汇编语言混合编程 (7)深入剖析Keil C51 ——从汇编到C51 (9)C语言和汇编语言的变量以及函数的接口问题 (14)汇编与C语言混合编程的关键问题 (15)KEIL段重定位 (15)用Keil在C中嵌入汇编早前公布了C和汇编混编的温度控制器程序,收到一些朋友的询问,他们无法在自己程序中使用我的18B20的汇编子程序或无法正常通过混编后的程序编译。
其实在KEIL中嵌入汇编的方法很简单。
如图一,在C文件中要嵌入汇编的地方用#pragma asm和#pragma endasm 分隔开来,这样编译时KEIL就知道这中间的一段是汇编了。
图1在有加入汇编的文件中,还要设置编译该文件时的选项图2Generate Assembler SRC File 生成汇编SRC文件Assemble SRC File 封装汇编文件(如图三的状态为选中)选上这两项就可以在C中嵌人汇编了,设置后在文件图示中多了三个红色的小方块。
图3为了能对汇编进行封装还要在项目中加入相应的封装库文件,在笔者的项目中编译模式是小模式所以选用C51S.LIB。
这也是最常用的。
这些库文件是中KEIL安装目录下的LIB目录中。
加好后就可以顺利编译了。
(注:我只在7.0以上版本使用过)图4在Keil中嵌入汇编1、其实在KEIL中嵌入汇编的方法很简单。
如图1,在C文件中要嵌入汇编的地方用#pragma as m和#pragma endasm分隔开来,这样编译时KEIL就知道这中间的一段是汇编了。
2、在有加入汇编的文件中,还要设置编译该文件时的选项,如图2所示。
3、Generate Assembler SRC File 生成汇编SRC文件Assemble SRC File 封装汇编文件(如图3的状态为选中)选上这两项就可以在C中嵌人汇编了,设置后在文件图示中多了三个红色的小方块。
C语言和汇编语言的互调

AX=83EC BX=0000 CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0013 NV UP EI NG NZ NA PE NC
143B:0013 8B5E06 MOV BX,[BP+06] SS:0004=04EC
int count[]={0,0,0,0,0};
position=buffer;
for (i=0;i<=4;i++){
count[i]=CHANGE(a[i],position);
p=position;
for (j=0;j<5-count[i];j++){
*p=' ';
p++;
}
position+=5;
-t
AX=0000 BX=0000 CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0010 NV UP EI NG NZ NA PE NC
143B:0010 8B4604 MOV AX,[BP+04] SS:0002=83EC
-t
AX=83EC BX=04EC CX=000ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0004
DS=142B ES=142B SS=143B CS=143B IP=001CNV UP EI NG NZ NA PE NC
143B:001C33D2 XOR DX,DX
-t
汇编与C语言的相互调用

汇编与C语言的相互调用汇编与C语言的相互调用一、实验目的阅读Embest EduKit-III启动代码,观察处理器启动过程;学会使用Embest IDE辅助信息窗口来分析判断调试过程和结果;学会在Embest IDE环境中编写、编译与调试汇编和C语言相互调用的程序。
二、实验设备硬件:PC机。
软件:Embest IDE Pro2004集成开发环境,Windows98/2000/NT/XP。
三、实验原理1.ARM过程调用ATPCS(ARM)ATPCS是一系列用于规定应用程序之间相互调用的基本规则,这此规则包括:支持数据栈限制检查;支持只读段位置无关(ROPI);支持可读/写段位置无关(RWPI);支持ARM程序和Thumb程序的混合使用;处理浮点运算。
使用以上规定的ATPCS规则时,应用程序必须遵守如下:程序编写遵守ATPCS;变量传递以中间寄存器和数据栈完成;汇编器使用-apcs开关选项。
关于其他ATPCS规则,用户可以参考ARM处理器相关书籍或登录ARM公司网站。
程序只要遵守ATPCS相应规则,就可以使用不同的源代码编写程序。
程序间的相互调用最主要的是解决参数传递问题。
应用程序之间使用中间寄存器及数据栈来传递参数,其中,第一个到第四个参数使用R0-R3,多于四个参数的使用数据栈进行传递。
这样,接收参数的应用程序必须知道参数的个数。
但是,在应用程序被调用时,一般无从知道所传递参数的个数。
不同语言编写的应用程序在调用时可以自定义参数传递的约定,使用具有一定意义的形式来传递,可以很好地解决参数个数的问题。
常用的方法是把第一个或最后一个参数作为参数个数(包括个数本身)传递给应用程序。
ATPCS中寄存器的对应关系如表3-5所列:ARM寄存器ARPCS别名APTCS寄存器说明R0~R3a1~a4参数/结果/scratch寄存器1-4R4v1局部变量寄存器1R5v2局部变量寄存器2R6v3局部变量寄存器3R7v4,wr局部变量寄存器4Thumb状态工作寄存器R8v5ARM状态局部变量寄存器5R9v6,sb ARM状态局部变量寄存器6RWPI的静态基址寄存器R10v7,s1ARM状态局部变量寄存器7数据栈限制指针寄存器R11v8ARM状态局部变量寄存器8R12ip子程序内部调用的临时(scratch)寄存器R13sp数据栈指针寄存器R14lr链接寄存器R15PC程序计数器2.main()函数与__gccmain()当应用程序中包含了main()函数,将会引起对C运行时库的初始化。
KEIL C51集成开发环境C和汇编语言的相互调用

KEIL C51集成开发环境C和汇编语言的相互调用
严天峰;王耀琦
【期刊名称】《兰州交通大学学报》
【年(卷),期】2008(027)001
【摘要】目前C语言已成为开发单片机项目的主要工具,但一些特殊的应用场合仍然需要汇编语言编写程序,如编写时序要求非常严格的接口协议时,这必然涉及到C 与汇编的相互调用,即混合编程的问题.详细介绍了KEIL C51环境下的C和汇编语言相互调用的方法和原则,并具体说明混合编程的细节和应注意的问题.
【总页数】4页(P131-134)
【作者】严天峰;王耀琦
【作者单位】兰州交通大学,电子与信息工程学院,甘肃,兰州,730070;兰州交通大学,电子与信息工程学院,甘肃,兰州,730070
【正文语种】中文
【中图分类】TP311.11
【相关文献】
1.Keil C51中C51程序与汇编程序的接口方法 [J], 张玉峰;荀建军
2.基于Keil C51集成开发环境的单片机教学探索 [J], 王青
3.基于Keil C51集成开发环境的单片机教学探索 [J], 王青
4.Keil C51中调用汇编语言的研究与实现 [J], 肖献保;方龙
5.基于80C51和KEIL C51的LED点阵显示系统 [J], 简献忠;虞箐;熊晓君;赵虎;居滋培
因版权原因,仅展示原文概要,查看原文内容请购买。
汇编程序和c语言相互调用实验、嵌入式系统实验

实验一一、汇编语言调用c语言主要内容为使用汇编语言调用C语言完成20!的计算。
将64位结果保存到寄存器R0、R1中,其中R1存放高32位结果1.建立汇编源文件start.s.global _start.extern Factorial.equ Ni,20.text_start:Mov R0,#NiBL FactorialStop:B Stop.end2.建立C语言源文件factorialLong long Factorial(char N){Char i;Long long Nx=1;For(i=1;i<=N;i++){Return Nx;}}二、C语言调用汇编语言在GUN ARM 编译环境下设计程序,用C语言调用ARM汇编语言C语言实现20!操作,并将64位结果保存到0xFFFFFFF0开始的内存地址单元,按照小端格式低位数据存放在低位地址单元。
1、建立C语言源文件main.c/* main.c */extern void Factorial(char Nx);Main(){Char N =20;Factoral(N);While(1);}2、建立汇编语言源文件factorial/* factorial.s */.global FactorialFactoral:Mov R8,R0Mov R9,#0SUB R0,R8,#1Loop:Mov R1,R9UMULL R8,R9,R0,R8MLA R9,R1,R0,R9SUBS R0,R0,#1BNE LoopLDR R0,=0xFFFFFFF0STMIA R0,{R8,R9}MOV PC,LR三、实验一内容在汇编语言中定义符号常量A和B,调用C语言程序求这两个数的最大值,返回汇编程序后,将结果存入R3。
(1)编汇编源文件start.s文件/*Start.s */.global _start.extern Factoiral.equ N1,20.equ N2,30.text_start:Mov R0,#N1Mov R1,#N2BL FactoralMov R3,R0Stop:B stop.end(2)编写C语言文件/* factorial.c*/int Factorial(int num1,int num2){if(a>=b) return a;else return b}用C语言编程,现将10000000开始的100个单元赋初值,然后求平均值、最大值和最小值,并将结果存放1在000100开始(1)编写汇编源文件start.s文件/*start.s*/global _startextern Factorial.text_start:B FactorialStopB stop.end(2)编写C语言文件/*Factorial.c*/Void Factrial(){int i;int 32-t,*p1,*p2; int max =*p1;long sum=0;double ove=0;p1=(int 32-t)0x10000000;p2=(int 32-t)0x10001000;for(i=0;i<=100;i++) *(p1+i)=i;for(i=1;i<=100;i++){if(*(p1+i)>max){max =*(p1+i);if(*(p1+i)<min)max=*(p1+i); }}ove=sum/100.0;*p2=sum;*(p2+2)=max;*(p2+3)=min;}实验二、GPIO延时函数static void delay_ms(int ms){int i,j;While(ms--){for(i=0;i<5;i++)for(j=0;j<514;j++);}}主函数Int main(void){GPX2PUD=GPX2PUD&(~(0x3<<4));GPX2CON=GPX2CON&(~(0xf<<28))|(0x1<<28); while(1){GPX2DAT=GPX2DAT|(0x1<<7);delay_ms(1000);GPX2DAT=GPX2DAT&(~(0x1<<7));delay_ms(1000);}return 0;}实验三、PWM定时器1.PWM的初始化void PWM_init(void){GPDO.CON=(GPDO.CON &~(0xf)) | 0x2; PWM.TCFGO=(PWM.TCFG0&~(0xFF))|0x63; PWM.TCFG1=(PWM.TCFG1 &~(0xF)) 0x3; PWM.TCNTBO=200;PWM TCMTBO=100;PWM.TCON=(PWM.TCON &~(0xF)) | OxA; PWM.TCON=(PWM.TCON &~(0xF)) | Ox9;}2.代码实现int main(void) {GPX2.CON=0x1<<28;PWM_init();while(1){GPX2.DAT=GPX2.DAT|0x1<<7;mydelay_ms(500);GPX2.DAT=GPX2.DAT & ~(0x1<<7);mydelay_ms(500);}return 0;}PWM输出软件设计PWM0初始化函数Void init_pwm0(void){PWM.TCFGO=PWM.TCFG0&(~(0xff<<0))|249; PWM.TCFG1=PWM.TCFG1&(~(0xf<<0))|4;//TCNT_CLK=PCLK(100M)/(249+1)/(16)=25KHZ) PWM.TCNTB0=100;PWM.TCNTB0=50;PWM.TCON=PWM.TCON|(0x1<<1);PWM.TCON=PWM.TCON&(~(0xf<<0))|(Ox9<<0))} 主函数int main(void){GPD0.PUD=0x0;GPD0.CON=GPD0.CON&(~(0xf<<0))|(0x2<<0); init_pwm0();while(1);return 0;}。
汇编函数与C函数的相互调用

昨天好好研究了一下内嵌汇编的情况。
更进一步的,该是看看独立编译的汇编程序与C/C++互相调用的情况了。
呵呵,最近怎么好像老在搞这个,想当年学习的时候,一门心思的学C++,到现在老是在弄诸如怎么在C/C++中调用LUA函数,或者反过来,怎么C/C++中调用Python函数,或者反过来,今天又是怎么在C/C++中调用汇编的函数,或者反过来。
呵呵,自从学习的语言越来越多,类似的情况碰到的也就越来越多了,但是,只懂一门语言就不能在合适的时候使用合适的语言来解决问题,并且看问题会带有狭隘的偏见,谁说的来着?毕竟无论是lua,python,asm都会有用的上的时候,我最近似乎老是喜欢说闲话。
这是某些哥们说的自己的见解,还是某些时候无聊的牢骚呢?谁知道呢,过年了嘛,还不让人多说几句话啊。
-_-!首先来看C中调用汇编的函数先添加一个汇编文件写的函数吧,在VS2005中对此有了明显的进步,因为就《加密与解密》一书描述,在2003中需要自己配置编译选项,但是在VS2005中很明显的,当你添加asm 文件后,可以自己选定masm的编译规则,然后一切就由IDE把你做好了,这也算是IDE的一个好用的地方吧。
非常不好的一点就是,VS2005中对于汇编没有任何语法高亮。
damnit!IDE怎么做的?就这点而言,其甚至不如一般的文本编辑工具!。
又是废话了。
因为是C,这个目前全世界可能是最具有可移植性的语言,所以问题要简单的多。
但是。
也不全是那么简单,先看看直觉的写法:汇编代码:PUBLIC GetArgument.486 ; create 32 bit code.model flat ; 32 bit memory model;option casemap :none ; case sensitive_TEXT SEGMENT PUBLIC 'CODE'GetArgument PROCMOV EAX, [ESP+4]RETNGetArgument ENDP_TEXT ENDSENDC语言代码:#include <stdio.h>#include <windows.h>int GetArgument(int);int _tmain(int argc, _TCHAR* argv[]){printf("%d/n",GetArgument(10));system("PAUSE");return 0;}声明是必不可少的,毕竟汇编没有头文件给你包含,不过多的话,可以考虑组织一个专门用于包含汇编函数实现的头文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AX=83EC BX=04EC CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0016 NV UP EI NG NZ NA PE NC
143B:0016 BF0400 MOV DI,0004
DS=142B ES=142B SS=143B CS=143B IP=0009 NV UP EI NG NZ NA PE NC
143B:0009 56 PUSH SI
-t
AX=0000 BX=0000 CX=003ADX=0000 SP=FFF2 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=000ANV UP EI NG NZ NA PE NC
*position=',';
position++;
}
*position=0;
printf("Number=%s\n",buffer);
for (i=0;i<5;i++){
printf(" %d,",count[i]);
}
printf("\n");
}
汇编语言程序
_TEXT segment BYTE PUBLIC 'CODE'
push si
push di
mov word ptr [bp-2],0 ;一个局部变量。赋值0,转换的ASCII码数量
mov ax,[bp+4] ;value的值
mov bx,[bp+6] ;buffer的值
mov di,4
mov cx,10
subloop1:
xor dx,dx
div cx ;DXAX/CX ,商在AX中,余数在DX中
assume CS:_TEXT
public _change
_change proc near ;int change(int value,char *buffer)
push bp
mov bp,sp
sub sp,4 ;定义局部变量的空间[bp-2],[bp-4]
push bx
push cx
push dx
Object filename [t3.OBJ]:(形成目标文件T3.obj)
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:
50160 + 415408 Bytes symbol space free
0 Warning Errors
0 Severe Errors(编译显示0错误)
-t
AX=83EC BX=04EC CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0004
DS=142B ES=142B SS=143B CS=143B IP=0019 NV UP EI NG NZ NA PE NC
143B:0019 B90A00 MOV CX,000A
143B:0003 83EC04 SUB SP,+04
-t
AX=0000 BX=0000 CX=003ADX=0000 SP=FFFA BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0006 NV UP EI NG NZ NA PE NC
二.实验步骤
1、下载TC.RAR到D盘,解压到D:\TC目录中;
2、把MASM.EXE拷贝到D:\TC中;
3、在D:\TC目录中建立两个文件DtoA.c和T3.asm,分别存放本题的C语言程序和汇编语言程序;
4、执行如下命令,编译T3.asm,形成目标文件T3.obj
msam T3.asm
5、执行如下命令,编译DtoA.c形成DtoA.obj文件,并把DtoA.obj和T3.obj链接,形成可执行文件DtoA.exe
DS=142B ES=142B SS=143B CS=143B IP=0020 NV UP EI PL ZR NA PE NC
143B:002080C230 ADD DL,30
-t
AX=0D31 BX=04EC CX=000ADX=0032 SP=FFF0 BP=FFFE SI=0000 DI=0004
143B:000A57 PUSH DI
-t
AX=0000 BX=0000 CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=000B NV UP EI NG NZ NA PE NC
143B:000B C746FE0000 MOV WORD PTR [BP-02],0000SS:FFFC=3302
实验报告
课程名称:C语言和汇编语言的互调
姓名
学号
组员
实验名称
C语言和汇编语言的互调
实验内容:(实验原理、实验步骤、数据处理、误差分析、程序算法、系统结构等)
一.实验原理
C语言参数传递原则
1、函数的返回值通过AX寄存器;
2、参数通过堆栈传递:参数传递的顺序是最后一个参数先入栈,第一个参数最后入栈;
3、在子程序中不对因传递参数而改变的SP进行校正,而在主程序中进行校正。
pop bp
ret
_change endp
_TEXT ends
end
五.运行
1.编译t3.asm
Microsoft (R) Mt (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
143B:0029 0BC0 OR AX,AX
-t
AX=0D31 BX=04EC CX=000ADX=0032 SP=FFF0 BP=FFFE SI=0000 DI=0003
DS=142B ES=142B SS=143B CS=143B IP=002B NV UP EI PL NZ NAPONC
143B:002B 75EF JNZ001C
AX=83EC BX=04EC CX=000ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0004
DS=142B ES=142B SS=143B CS=143B IP=001E NV UP EI PL ZR NA PE NC
143B:001E F7F1 DIV CX
-t
AX=0D31 BX=04EC CX=000ADX=0002 SP=FFF0 BP=FFFE SI=0000 DI=0004
-t
AX=83EC BX=0000 CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0013 NV UP EI NG NZ NA PE NC
143B:0013 8B5E06 MOV BX,[BP+06] SS:0004=04EC
int count[]={0,0,0,0,0};
position=buffer;
for (i=0;i<=4;i++){
count[i]=CHANGE(a[i],position);
p=position;
for (j=0;j<5-count[i];j++){
*p=' ';
p++;
}
position+=5;
tcc DtoA.c T3.obj
6、执行T3.exe。
三. 流程图
四.程序
C语言程序
#include <stdio.h>
extern int CHANGE(int,char *);
main(){
int a[5]={276,13965,1024,4,32},i,j;
char buffer[32],*p,*position;
-t
AX=0000 BX=0000 CX=003ADX=0000 SP=FFF0 BP=FFFE SI=0000 DI=0000
DS=142B ES=142B SS=143B CS=143B IP=0010 NV UP EI NG NZ NA PE NC
143B:0010 8B4604 MOV AX,[BP+04] SS:0002=83EC
add dl,30h
mov byte ptr [bx+di],dl
inc byte ptr [bp-2] ;已转换的字符数
dec di ;下一个字符保存的位置
or ax,ax
jnz subloop1
mov ax,[bp-2] ;放回结果
pop di
pop si
pop dx
pop cx
pop bx
add sp,4
DS=142B ES=142B SS=143B CS=143B IP=0023 NV UP EI PL NZ NAPONC
143B:0023 8811 MOV [BX+DI],DL DS:04F0=FF
-t
AX=0D31 BX=04EC CX=000ADX=0032 SP=FFF0 BP=FFFE SI=0000 DI=0004
2.编译dtoa.c
D:\tc>Tlink T3.obj
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International