It's pretty hard for me to embed assembler statements in the C language.

Source: Internet
Author: User
Tags intel pentium

I saw a post on the CSDN forum this morning http://topic.csdn.net/u/20120917/14/82f42e17-977a-4824-95bd-7b79db15d283.html: "C language embedded in the assembly, What is the point? ”

One example is to insert a piece of assembler code into the C language to get the CPU's frequency, manufacturer and model:

//=====================================================================================
/* The CPUID instruction is the assembly instruction for obtaining CPU information under the Intel IA32 architecture,
Can get CPU type, model, manufacturer information, trademark information, serial number,
Cache and other CPU-related things.
*/
#include <windows.h>
#include <iostream>
#include <string>

using namespace Std;


Information for storing Eax,ebx,ecx,edx four registers
DWORD Deax;
DWORD DEBX;
DWORD decx;
DWORD Dedx;

void Execpuid (DWORD veax)//Initialize CPU
{
__asm
{
MOV eax,veax
Cpuid
MOV deax,eax
MOV debx,ebx
MOV decx,ecx
MOV Dedx,edx
}
}

/* There is a part called "Timestamp (time Stamp)" in the CPU above Intel Pentium.
It is a 64-bit unsigned integer number that records the number of clock cycles that have elapsed since the CPU was power-up.
Because the current CPU frequency is very high, so this component can achieve the nanosecond level of timing accuracy.
This accuracy is unmatched by the above two methods.
In CPUs above Pentium, a machine instruction RDTSC (Read time Stamp Counter) is provided.
To read the number of the timestamp and save it in the EDX:EAX register pair
*/
Long Getcpufreq ()//Get CPU frequency, Unit: MHZ
{
int start,over;
_asm
{
RDTSC
MOV start,eax
}
Sleep (50);
_asm
{
RDTSC
MOV over,eax
}
Return (Over-start)/50000;
}

/* eax = 0 As the input parameter, you can get the manufacturer information of the CPU.
After the CPUID instruction is executed, a 12-character manufacturer's information is returned,
The first four characters of the ASC code are placed low to high in the EBX, the middle four in edx, and the last four characters on the ECX.
*/
String Getmanid ()//Get manufacturer information
{
Char id[25];
memset (id,0,sizeof (ID));

Execpuid (0); Initialization
memcpy (id+0,&debx,4); Copy manufacturer information to an array
memcpy (id+4,&dedx,4);
memcpy (id+8,&decx,4);

return string (ID);
}


/* Right click on my Computer, select Properties, you can see a CPU in the window below the information,
This is the trademark string for the CPU. The CPU's trademark string is also obtained through the CPUID.
Because the trademark string is very long (48 characters), it cannot be obtained when the CPUID instruction is executed.
So Intel divided it into 3 operations, the input parameters of the eax were 0x80000002,0x80000003,0x80000004,
Each return of 16 characters, according to the order from low to high place in eax, EBX, ECX, edx.
Therefore, you can save the results in a circular manner, after each execution, and then perform the next cpuid.
*/
String Getcputype ()
{
Const DWORD ID = 0x80000002; From 0x80000002 onwards, to 0x80000004 end
Char cputype[49];//used to store CPU model information
memset (cputype,0,sizeof (Cputype));//Initialize array

for (DWORD t = 0; t < 3; t++)
{
Execpuid (id+t);
Each time the loop ends, the information is saved to the array
memcpy (cputype+16*t+ 0,&deax,4);
memcpy (cputype+16*t+ 4,&debx,4);
memcpy (cputype+16*t+ 8,&decx,4);
memcpy (cputype+16*t+12,&dedx,4);
}

return string (Cputype);
}

void Main ()
{
cout<< "Native CPU information is as follows:" <<endl;
cout<< "CPU Frequency:" <<getcpufreq () << "MHZ" <<endl;
cout<< "CPU Manufacturer:" <<getmanid () <<endl;
cout<< "CPU Model:" <<getcputype () <<endl;
Cin.get ();

}

Immediately came to interest, this example is written in C + + syntax, I opened codeblocks simple changed a few places to become C, and then compiled, there have been a lot of errors.

After one hours of exploration, first of all understand that in Codeblocks + GCC can embed assembly statements, which is certain.

Because I found a simple example on the Internet:

#include <stdio.h>

This is the VC6 below.

/*

int sum (int a,int b)
{
__asm
{
mov eax, [ebp+8]
add eax, [ebp+0ch]
}
}

*/

This is what GCC is writing.

int sum (int a, int b)
{
__asm__
(
"Movl 8 (%EBP),%eax;"
"Addl (%EBP),%eax;"
);
}


int main ()
{
printf ("1 + 2 =%d\n", sum);

return 0;
}

The program can compile and execute normally.

But why the code that gets the CPU information is always prompt when compiling:

Too many memory references for MOV

And then I found this article: http://topic.csdn.net/u/20070416/13/82e4047a-c812-43d4-a28e-e67ddf6c9ad6.html

Netizens main tip:

You should learn the ATT syntax first.
__asm__ ("Subl%0,%%esp":: "M" (Paramnumber));
__asm__ ("Movl%0,%%ecx":: "M" (Paramnumber));
__asm__ ("Movl%0,%%esi":: "M" (parameters));
__asm__ ("Movl%esp,%edi");
__asm__ ("Rep movsb");

See this, I intend to give up the rewrite, this att syntax look at the head big, do not intend to do again.

If you need to use it someday, learn from the beginning.

2012-09-20

It's pretty hard for me to embed assembler statements in the C language.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.