我不知道是否有可以将ASM转换为C的程序。我检查了谷歌,我已经读过IDA Pro可以做到但我不知道如何做。无论如何,如何将这部分用ASM编写的代码转换为C?
以下是代码:
#define CALIBRATIONTIME .10 ;Number Of Times To Measure Signal During Calibration
;**********************************************************************************************
;Calibrate() - Measures A Period From The Input(GP0) Reference Signal
; - Updates Osccal Value
; - Updates E^2
;**********************************************************************************************
CALIBRATE
movlw CALIBRATIONTIME
movwf COUNTER ;Calibration Counter
LOW0
btfsc INPUT0 ;Wait To Sample Low Edge #0 (Makes Sure We Are Synchronized First Time Through)
goto LOW0
HIGH1
btfss INPUT0 ;Wait To Sample High Edge #1
goto HIGH1
clrf TMR0 ;Start Timer (Timer Will Be Behind By 5us After This Instruction)
LOW1
btfsc INPUT0 ;Wait To Sample Low Edge #1
goto LOW1
HIGH2
btfss INPUT0
goto HIGH2
movf TMR0,W ;Stop Timer (Timer Will Be Stopped 3us Late)
addlw .2 ;Timer Is Behind By 2us Total From Start To Stop
call CHECKPERIOD ;See If Osccal Needs To Be Adjusted
LOW2
btfsc INPUT0 ;Wait To Sample Low Edge #2
goto LOW2
decfsz COUNTER,F ;Decrement The Calibration Counter
goto HIGH1
call UPDATE_EE ;Update E^2
return
答案 0 :(得分:7)
这似乎适用于PIC18F单片机。是?见http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/
PIC非常老,可能无法支持C.您是否尝试在C中重写PIC或转换为其他架构? PIC有可靠的C编译器和工具链吗?
对于基本的asm,左边的符号是"标签",就像在C中一样。
PIC有许多指令,如果是真的"测试条件并跳过下一条指令"。
例如,第一个循环具有标签" LOW0"。在C中,这看起来像:
LOW0:
if (INPUT0 != 0)
goto LOW0;
清理它:
while (INPUT0 != 0);
但是,有许多未定义的符号:INPUT0,TMR0,COUNTER。 INPUT0似乎是存储器映射的I / O端口,TMR0也是如此。 COUNTER看起来像一个普通的全球,但你必须弄清楚哪个是哪个。
有些调用未定义的其他子程序。他们是集会还是C?如果汇编,参数的调用约定是相同的吗?
如果其他所有内容都已移植到C,并且这只是一个落后者,重新编码它是微不足道的。如果我回答了上述问题中的更多问题,我可以用比写这篇文章更短的时间来记录整个事情。
如果您的项目正在离开PIC拱门,那么它是有道理的。什么是动机[和背景]?
更新:
我已下载完整档案并对其进行了分析。警告:虽然我已经做了30多年的C和40多岁的装配工,但我是PIC18F的新手,但我已经能够借鉴这些经验。
PIC是一个8位微控制器,带有一个通用寄存器,称为" W"或者"工作注册"。它还有"注册文件",由" F"表示。它有一些指令可以将字节移入/移出W和给定寄存器文件中的给定寄存器。稍后会详细介绍。
打印 [重复:打印]所有相关文件/网页。创建一本书。
PIC相对简单,指令相对较少。我建议你在汇编程序中进行分析。当你充分了解asm和arch实际转化为C时,你实际上能够理解asm。
C的类比是你只允许这样做:
if (x) goto label
if (! x) goto label
foo() // with _no_ arguments
W = ...
F[idx] = W
W = F[idx]
首先,p12f675.inc是PIC的主定义文件。它只是一堆定义。请注意";"是注释字符,相当于C&C的ANSI" //" [他们都是"全线"]。 " EQU"就像一个C enum。如果您想将整个文件转换为C .h文件,请更改所有";"进入" //"。把" enum {"在顶部"};"在底部。然后改变所有:
OSCCAL EQU H'0090'
成:
OSCCAL = 0x0090,
你实际上并不需要这样做,我建议不要这样做。只需咬紧牙关,熟悉EQU语法。
以下是一般资源:http://www.pic18f.com/,本教程将非常有用入门:http://www.pic18f.com/tutorial/2007/12/04/18f4550-and-assembly-overview/
对于每个asm / machine指令,使用我提到的原始站点,打印给定页面以获取给定指令。例如,对于" movwf",请打印此页:http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/MOVWF.html
真的没有那么多。而且有些人不在索引页面中。只是谷歌他们。实际上,打印索引页面上的每个链接可能更容易。然后,您将拥有完整的"指令集参考"
PIC寄存器文件"存储"。我能想到的最接近的类比是考虑一个2-Dim C数组:" F [2] [256]"。但是,您无法直接访问F [y] [x]。你必须做一个" selectY(1)" [选择"银行" 1]和a" getF(x)" [获取给定银行中的第x个寄存器]。请参阅.inc文件以获取给定银行的x值。并非x的所有值都可能对给定的银行有效。说不上。
寄存器文件中的一些寄存器是I / O端口(例如GPIO)。有些是内部的,例如STATUS。因此,在您将给定的F寄存器(例如STATUS)传送到W寄存器之后,您可以检查各个位。在.inc文件中,有" C"和#34;等等#34; [处理器"携带"旗帜]和" Z" [CPU"零"标志"。]
请注意" .whatever"表示一个常数值(与内存位置相对)。
请注意,代码的INIT部分的倒数第二部分是BANKSEL GPIO。因此,当我们执行LOW0循环时,INPUT0被" GPIO,0"取代。这意味着寄存器GPIO的第0位,它是存储区0中的寄存器5。
在C中,必须标记对硬件寄存器的访问&#34; volatile&#34;,因此,为了说明,F应为&#34; volatile unsigned char F [2] [256]&#34;。< / p>
所以,重新编码&#34; LOW0&#34;再次:
LOW0:
if ((F[0][0x0005] & (1 << 0)) != 0)
goto LOW0
另外,您的main.asm有很好的评论。尝试忽略asm insts,只需阅读几次评论。然后返回并阅读指令定义几次。交叉引用它们。
哦,是的。在方格纸上绘制寄存器文件可能会有所帮助。
笔比剑更强大。要理解asm,笔和纸可能比计算机更强大: - )