本文目录一览:
汇编语言与C语言转换
程序有很多问题,做了部分修改
#includereg51.h
#define uchar unsigned char
sbit p10=P1^0;
sbit p30=P3^0;
sbit p31=P3^1;
sbit p12=P1^2;
void delay()
{
uchar i,j;
for(i=0;i170;i++)
for(i=0;i187;i++);
}
void alarm()
{
uchar times;
p12=1;
p30=0;
p31=0;
times=0x14;
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
TR=1;
while(times)
{
while(TF0==0);
TF0=0;
TH0=0x3c;
TL0=0xb0;
times--;
}
p30=1;
p31=0;
p12=0;
}
void pint0() interrupt 0
{
EX0=0;
if(p32==0)
{
delay();
if(p32==0)
{
p30=1;
p31=0;
p12=0;
}
}
EX0=1;
}
main()
{
IE=0x81;
IT0=1;
SP=0x30;
p30=1;
p31=1;
P1=0xff;
P2=0x00;
p12=0;
while(1)
{
if(p10==0)
{
delay();
if(p10==0)alarm();
}
}
}
单片机C51,将汇编语言转换为C语言
#includereg52.h
#define u8 unsigned char
#define u16 unsigned int
#define BufSize 0x10
u8 buf[BufSize];
u8 js=0;
void main(){
SCON=0x80;
PCON=0x80;
EA=1;
ES=1;
ACC=buf[0];
TB8=P;
SBUF=ACC;
while(1);
}
void TRANI()interrupt 4
{
TI=0;
js++;
if(js==BufSize){
ES=0;
}
else{
ACC=buf[js];
TB8=P;
SBUF=ACC;
}
}
顺便优化汇编代码
BUF EQU 0X50
ORG 0000H
JMP MAIN
ORG 0023H
JMP TRANI
MAIN:
MOV SCON,#0X80;
MOV PCON,#0X80
SETB EA
SETB ES
MOV R0,#BUF
MOV A,@R0
MOV C,P
MOV TB8,C
MOV SBUF,A
JMP $
TRANI:
PUSH PSW
PUSH ACC
INC R0
CJNE R0,#BUF+0x10,NEXT
JMP TEND
NEXT: MOV A,@R0
MOV C,P
MOV TB8,C
MOV SBUF,A
TEND:
POP ACC
POP PSW
RETI
如何将这段汇编语言转换成C语言
如何将这段汇编语言转换成C语言?题目分别提供了同一C语言代码的32位和64位汇编版本:很容易可以得出其源C语言代码:
int f(int** p){
return (**p=**p+4,*(int*)**p);
}
则函数体的返回值类型是int,参数p的类型是int**,其唯一的语句是return (**p=**p+4,*(int*)**p);
先把结论放在这,节约不想思考的同学的时间,不同编译器可能会有所不同,lea 0x4(%eax),%ecx指令可能会被编译器拆开成两段:mov (%eax),%ecx 和add 0x4,%ecx(对于64位,则是编译器把lea lea 0x4(%rax),%rcx,拆开成mov (%rax),%rcx 和add 0x4,%rcx,但是效果是一样的。
根据题目中函数体只有1句代码的信息,我们至少确定了这个代码是一个return语句,如此短小的函数当然只需要用到段内跳转和段内指针,不需要段地址信息,所以指针大小(64位的RIP和32位的EIP)只是偏移量大小,分别为64位(8字节)和32位(4字节)。
题目的设问有相当好的引导性,对比查看左边和右边的倒数第3个指令,我们可以看出:函数的返回值都是放在eax变量之中,说明返回值的类型大小是4个字节。而同时,我们知道在C语言中,64位和32位环境下,int类型的大小都是4个字节,所以第1空的答案不能是只有1字节的char类型,也不能是在32位环境下大小为4字节而在64位环境下大小为8字节的指针类型如char*、int*。综上,第1空的答案:函数f的返回值类型只能是int。
第2空则是考查C语言函数的参数传递,栈式参数传递,在call函数f把ip压入(分别为64位的RIP和32位的EIP)之前,先压入的是函数的实际参数,其类型暂时不知道,那就得从汇编指令中找出这个信息点:
C语言函数体标志就是:push %ebp→mov %esp,%ebp→函数体内部→pop %ebp→ret(对64位则是:push %rbp→mov %rsp,%rbp→函数体内部→pop %rbp→retq)
两边都是同一个简单的c语句得到的汇编语句(64位和32位),左边64位的第2、3、4行对应于右边的第2、3行(64位多用了一个rdi寄存器传递参数,可能是编译器选项不同的缘故,又因为main函数中调用函数f的指令没有给出,且不一定相同,故不影响判断)。
两边剩下的几行代码(左边2、3、4、5、6、7、8行,右边2、3、4、5、6、7行)的工作大同小异,从数据流上看(函数体内,对于32位0x8(%ebp)是第一个也是唯一一个参数,对于64位-0x8(%rbp)才是):
*p→eax,*eax→eax,eax+4→ecx(①),*p→edx,ecx→*edx,*eax→eax
可以简化为:
**p→eax,eax+4→ecx,ecx→**p,***p→eax
再简化为
**p+4→**p,***p→eax
注:(①)lea 0x4(%eax), %ecx 意思是取有效地址Load Effect Address,相比于mov 0x4(%eax), %ecx使用地址所指向的值*(eax+4)→ecx,lea指令只使用地址的值eax+4→ecx,少做一步。64位也是如此a。
(对于64位则是:
*p→rax,*rax→rax,rax+4→rcx,*p→rdx,rcx→*rdx,*rax→eax
可以简化为:
**p→rax,rax+4→rcx,rcx→**p,***p→eax
再简化为
**p+4→**p,***p→eax
)
看到数据流了,C语言语句自然也就呼之欲出了,即return (**p=**p+4,*(int*)**p)。(逗号,运算符的意思是从左到右计算式子,然后返回最后一个)
注意这里的+4指的是4个字节,而在64位32位中都一样,于是初步断定**p是固定大小类型变量,同时返回值是int类型的,故认为它(**p)是int,所以参数p的类型就是int**。
请问如何把汇编语言转成C语言
反过来是可以的,叫反汇编,但汇编无法转C,因为汇编是机器语言,C最终还是转化成汇编,想转的话只能人为的编一个C出来
怎么把汇编转换成C语言
如果 只是简单的几行,可以把编译后的exe文件,用系统自带的debug(windows键+R打开 运行窗口 输入debug 空格 exe的路径)打开debug后,输入U可以看到几行汇编代码。
如果是源代码 在vs编译器中调试运行,菜单上的:调试--窗口--反汇编 可以查看,如果是其他编译器 仔细找找也带反汇编的
要资料的话 [天书夜读-从汇编语言到Windows内核编程].谭文.邵坚磊. 这本书的基础部分里 有c语言与汇编的转换