Assembly 如何将汇编语言中的代码转换为C代码?

Assembly 如何将汇编语言中的代码转换为C代码?,assembly,avr,Assembly,Avr,我有汇编代码,想转换成c语言中的等效代码,我想这是 添加,但如果只是简单的添加,则需要帮助和thnx: 闪光检查和: clr ZH clr ZL clr XH clr XL FCK_1: lpm R1,z+ add XL,R1 brcc FCK_2 inc XH ;carry set so inc Hi Bit FCK_2: cpi ZH,HIGH(BSTART*2 -16) brne FCK_1 cpi ZL,LOW(BSTART*2 -16) brne FCK

我有汇编代码,想转换成c语言中的等效代码,我想这是
添加,但如果只是简单的添加,则需要帮助和thnx:

闪光检查和:

 clr ZH
 clr ZL
 clr XH
 clr XL 

FCK_1: 

lpm R1,z+
add XL,R1 
brcc FCK_2
inc XH   ;carry set so inc Hi Bit

FCK_2:

cpi ZH,HIGH(BSTART*2 -16) 
brne FCK_1 
cpi ZL,LOW(BSTART*2 -16) 
brne FCK_1

lpm R0,Z+ 
lpm R1,Z 
cp R0,XH 
brne CK_Fail 
cp R1,XL 
brne CK_Fail 
ret
CK_Fail:

将其转换为C代码并不能回答您的实际问题。描述程序集正在执行的操作将更有帮助

X和Z寄存器实际上各有两个寄存器,因此它们有两个字节长。有些指令使用Z寄存器作为输入地址。这就是代码中发生的情况

该函数从地址0开始,逐字节向16位X寄存器添加

lpm R1,z+  ; load the byte at address Z into R1 and post-increment Z
add XL,R1  ; Add R1 to X
如果低字节溢出,则有一些代码增加X的高字节(通常的加法算法)

循环一直持续到Z到达
BSTART*2-16
,这似乎是校验和之前的所有字节

最后一部分将存储的校验和加载到R0和R1中,然后将其与代码刚刚在X(XH和XL)中计算的校验和进行比较


如果校验和失败,则代码跳过返回语句,继续执行校验和函数后的代码,这可能向用户指示某种类型的错误情况。

可能是这样的:

typedef union {
    unsigned short u16;
    unsigned char u8[2];
} Pointer;

const Pointer BSTART = ???;

int Flash_Check_SUM( Pointer Z, Pointer X ){

    unsigned char XH = ((unsigned char *)&X)[0];
    unsigned char XL = ((unsigned char *)&X)[1];
    unsigned char ZH = ((unsigned char *)&Z)[0];
    unsigned char ZL = ((unsigned char *)&Z)[1];

AddZ:
    unsigned short R1 = *Z++;
    X += *R1;
    if( XH > 0 ) goto IsEqual;
    XH++;

IsEqual:
    if( ZH != ((unsigned char *)&(BSTART * 2 - 16))[0] ) goto AddZ;
    if( ZL != ((unsigned char *)&(BSTART * 2 - 16))[1] ) goto AddZ;
    unsigned short R0 = *Z++;
    R1 = *Z;
    if( R0 != XH ) return -1;
    if( R1 != XL ) return -1;
    return 0;
}

使用
adc XH
而不是
inc
上的分支不是更容易吗?无论如何,你没有说你在理解这一部分方面有困难,而且asm中也没有评论。确切地解释每一条指令的作用以及为什么完整的细节会花费太长的时间,所以投票决定结束太宽。坦白地说,我不理解汇编,但我知道这部分是关于校验和的,是通过加法完成的,所以我想确保这是正常的加法@petercordes@PeterCordes不,
adc
无法工作。代码将单个字节相加为16位。必须有一条类似于“带进位将立即数添加到字节”的指令才能将0添加到带进位的XH中,但没有。看起来这个函数将字节ptr[0]添加到字节ptr[BSTART*2-18],并将总和与单词ptr[BSTART*2-16]进行比较?@UncleO:哦,我明白了,谢谢。x86有一个adc立即数,但我想如果在循环中执行此操作,AVR可以使用零寄存器。我猜AVR中的分支相当便宜,但是由于这个加法发生在循环内,可能值得在循环外清除一个额外的寄存器,因为。一些问题:1)为什么在加法时要取消对R1的引用?2) 转到IsEqual的
有什么好处?3) 你能不能把
(256*ZH+ZL)
(BStart*2-16)
进行比较?@tommyle2k 1)我假设寄存器被建模为指针,2)我省略了我添加的一行代码,3)我试图或多或少地逐字翻译代码,但没有使C中的各种简化成为可能。我将用这个simpe循环替换asm函数:
intcsum(char*Z){unsigned short sum=0;do{sum+=*Z++;}while(Z!=BSTART*2-16);return(*Z++==(sum/256)和&*Z==(sum%255));}