C语言与汇编的嵌入式编程:求100以内素数
写汇编之前,需要搞清楚C语言代码的写法,这里以最简单的算法举例说明
C代码如下:
#include <stdio.h>
void main(){ int i,j;
int count=; for(i=;i<=;i++)
{
for(j=;j<i/;j++)
{
if(i%j==)
{
count=;
break;
}
} if(count == )
{
printf("%d\n",i);
}
count = ;
}
}
由于C语言中使用的是for进行循环,使用VC调试汇编时,发现for汇编的jmp需要具体地址才可以进行,对于程序来讲不方便

然后查找资料,汇编中可以使用loop循环,因此,先实现一个loop循环
#include <stdio.h>
void main(){ //test loop
_asm{ mov ax, mov cx, s:add ax,ax loop s };
}
进一步,我们在loop循环里面加上printf输出语句
#include <stdio.h>
void main(){ int i=0xA; // dword ptr [ebp-4],0Ah
int j=0xB; // dword ptr [ebp-8],0Bh
int count=; // dword ptr [ebp-0Ch],1 //第一个循环start
_asm{
mov eax, // i=2
mov ecx, // i<100
loop1: // 开始循环1
mov i,eax // 保存i
push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
push ecx
}; printf("\n\n第一层循环i=%d\n",i); //第一个循环end
_asm{
pop ecx
pop eax
add eax, // i++
loop loop1
}; printf("ssssssssss"); }

在此基础上,我们
再实现一个loop循环里面嵌入一个loop循环,即可达到for循环里面嵌套for循环的目的
#include <stdio.h>
void main(){ int i=0xA; // dword ptr [ebp-4],0Ah
int j=0xB; // dword ptr [ebp-8],0Bh
int count=; // dword ptr [ebp-0Ch],1 //第一个循环start
_asm{
mov eax, // i=2
mov ecx, // i<100
loop1: // 开始循环1
mov i,eax // 保存i
push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
push ecx
}; printf("\n\n第一层循环i=%d\n",i); //第二个循环start
_asm{
mov eax, // j=2
mov ecx,i // j<i
sub ecx, // j=i-2
loop2: // 开始循环2
mov j,eax // 保存j
push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
push ecx
}; printf("j=%d\t",j); //第二个循环end
_asm{
pop ecx
pop eax
add eax, // j++
loop loop2
}; //第一个循环end
_asm{
pop ecx
pop eax
add eax, // i++
loop loop1
}; printf("ssssssssss"); }

最后在循环过程中,加上是否为素数的判断if语句,即可简单实现C语言与汇编的嵌入式编程。
改造后的代码:
#include <stdio.h>
void main(){ int i=0xA; // dword ptr [ebp-4],0Ah
int j=0xB; // dword ptr [ebp-8],0Bh
int count=; // dword ptr [ebp-0Ch],1 //第一个循环start
_asm{
mov eax, // i=2
mov ecx, // i<100
loop1: // 开始循环1
mov i,eax // 保存i
push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
push ecx
}; printf("\n\n第一层循环i=%d\n",i); //第二个循环start
_asm{
mov eax, // j=2
mov ecx,i // j<i
sub ecx, // j=i-2
loop2: // 开始循环2
mov j,eax // 保存j
push eax // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
push ecx
}; //判断是否为素数
if(i%j==)
{
count+=;
} /*
_asm{
//if(i%j==0)
mov eax,i
cdq
idiv eax,j
test edx,edx
jne loop2+2Ah (0040d822)
//{
//count+=1;
mov edx,dword ptr [ebp-0Ch]
add edx,1
mov dword ptr [ebp-0Ch],edx
//}
}*/ printf("j=%d,count=%d\t",j,count); //第二个循环end
_asm{
pop ecx
pop eax
add eax, // j++
loop loop2
}; if(count ==)
{
printf("%d是素数\n",j);
} count =; //第一个循环end
_asm{
pop ecx
pop eax
add eax, // i++
loop loop1
}; printf("ssssssssss"); }
最后,还可以将if,printf等转换为汇编
总结下思路;
1、先用C语言写好一个算法程序
2、使用loop代替for循环
3、在loop循环中加入printf输出语句,实现循环变量值得打印
4、在loop循环中嵌入loop循环
5、加上判断等其他语句
6、再将第5步的判断等其他语句再统一转换成汇编代码。
C语言与汇编的嵌入式编程:求100以内素数的更多相关文章
- python求100以内素数
python求100以内素数之和 from math import sqrt # 使用isPrime函数 def isPrime(n): if n <= 1: return False for ...
- C语言与汇编的嵌入式编程:统计字符串中各字符出现的次数
原始C语言: #include<stdio.h> void main(){ ]; char pipei[] = "abcdefghijklmnopqrstuvwxyz" ...
- C语言与汇编的嵌入式编程:main中模拟函数的调用(两数交换)
编写一个两数交换函数swap,具体代码如下: #include<stdio.h> void swap(int *p1,int *p2) { int temp; temp = *p1; *p ...
- Java简单算法--求100以内素数
package cn.magicdu.algorithm; /** * 打印素数 * * @author xiaoduc * */ public class Prim { public static ...
- while做法1.兔子生兔子 2.求100以内质数的和3.洗发水15元 牙膏5元 香皂2元 150元的算法
1.兔子生兔子 2.求100以内质数的和 3.150块钱花完问题
- while:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完
1.兔子生兔子问题: 2.打印菱形 3.求100以内质数的和 4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完有多少种情况?
- for嵌套:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和
1.兔子生兔子问题 方法一: 方法二: 2.打印菱形 3.求100以内质数的和
- Python练习题 026:求100以内的素数
[Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...
- 斐波那契数列(递归)&求100以内的素数
Java 5 添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序.它是以 前的 StringTokenizer 和 Matcher 类之间的某种结合.由于任何数据都 ...
随机推荐
- Hibernate:对象关系映射(一对一,一对多,多对一,多对多)
如需转载,请说明出处:http://www.cnblogs.com/gudu1/p/6895610.html Hibernate通过关系映射来表示数据库中表与表之间的关系,关系映射可以通过两种方式:配 ...
- http请求常见错误状态码
一.HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无法重复此请求. 原因:(调用方接口方法的实参和服务器接口方法的形参不一致) 1.前端提交数据 ...
- RS-232C
RS-232C标准(协议)的全称是EIA-RS-232C标准,定义是"数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准".它是在1970年由美国电子 ...
- mysql(4):性能分析和性能优化
性能分析 慢查询日志分析 ①查询慢查询日志的状态 show global variables like '%slow_query_log%'; ②开启慢查询日志(当mysql重启时会重置) set g ...
- C#泛型应用及原理
https://blog.csdn.net/ananlele_/article/details/97623254 https://blog.csdn.net/kebi007/article/detai ...
- windows系统安装 ionic
windows系统安装 ionic 参考菜鸟教程:https://www.runoob.com/ionic/ionic-install.html 命令行安装 Window 和 Linux 上打开命令行 ...
- linux deploy---旧手机变废为宝
前几天朋友送了我一部红米Note 1s,本来不想要,转念一想,不要白不要,就收了. 拿到之后我就想,这么一个1+8的手机能做什么呢? 翻遍了CSDN和简书,找到了一个性价比不错的方法:给旧手机装上一个 ...
- eureka服务只能设置8761,不然服务无法注册
原因是,eureka服务端和eureka的客户端在一个project下,只是属于不同的模块.所以出现了以上问题.分开项目就好了.
- HTML前端入门归纳——样式
本人一直在从事.net的开发,界面都是采用的WPF,近期花了一个多月进行HTML前端的学习,在这里呢进行学习总结和归纳. 本系列将主要分为4个模块: 控件 样式 布局 JavaScript 根据多年W ...
- AcWing 837. 连通块中点的数量
#include <iostream> using namespace std; ; int n, m; int p[N], size[N]; int find(int x) { if ( ...