Reputation: 29
In AT&T syntax you can do something like asm("mov %%eax, %0\n\t":"=r" (a[0])); but not in intel syntax. I want to translate this AT&T syntax to intel syntax, it gets the cpu brand name and print it.
int a[10];
void brandString(int eaxValues)
{
if (eaxValues == 1) {
__asm__("mov $0x80000002 , %eax\n\t");
}
else if (eaxValues == 2) {
__asm__("mov $0x80000003 , %eax\n\t");
}
else if (eaxValues == 3) {
__asm__("mov $0x80000004 , %eax\n\t");
}
__asm__("cpuid\n\t");
__asm__("mov %%eax, %0\n\t":"=r" (a[0]));
__asm__("mov %%ebx, %0\n\t":"=r" (a[1]));
__asm__("mov %%ecx, %0\n\t":"=r" (a[2]));
__asm__("mov %%edx, %0\n\t":"=r" (a[3]));
printf("%s", &a[0]);
}
void getCpuID()
{
__asm__("xor %eax , %eax\n\t");
__asm__("xor %ebx , %ebx\n\t");
__asm__("xor %ecx , %ecx\n\t");
__asm__("xor %edx , %edx\n\t");
printf("Brand string is ");
brandString(1);
brandString(2);
brandString(3);
printf("\n");
}
int main(){
getCpuID();
}
and, so far, I have done:
char a[10];
void brandString(int eaxValues)
{
if (eaxValues == 1) {
__asm {
mov eax, 0x80000002
}
}
else if (eaxValues == 2) {
__asm {
mov eax, 0x80000003
}
}
else if (eaxValues == 3) {
__asm {
mov eax, 0x80000004
}
}
__asm {
cpuid
mov a[0], eax
mov a[1], ebx
mov a[2], ecx
mov a[3], edx
}
printf("%s", &a[0]);
}
void getCpuID() {
__asm {
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
}
printf("Brand string is ");
brandString(1);
brandString(2);
brandString(3);
printf("\n");
}
but obviously you can not do mov a[0], eax so I'm stuck, I do not know how to do it.
Upvotes: 2
Views: 104
Reputation: 29
unsigned int regs[4];
char brand[49] = {0};
// Inline assembly to call CPUID with given eax value and store results in regs
#define cpuid(eax_val, regs) \
__asm__ __volatile__ ( \
"cpuid" \
: "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) \
: "a" (eax_val) \
);
// Call CPUID with 0x80000002, 0x80000003, and 0x80000004 and store the brand string
cpuid(0x80000002, regs);
memcpy(brand, regs, sizeof(regs));
cpuid(0x80000003, regs);
memcpy(brand + 16, regs, sizeof(regs));
cpuid(0x80000004, regs);
memcpy(brand + 32, regs, sizeof(regs));
printf(" Brand string is: %s\n\n", brand);
The characteristics of this code are:
Macro for CPUID:
Defines a macro cpuid to encapsulate the cpuid instruction. This macro takes eax value and a register array as parameters.
Direct Memory Copy:
Uses memcpy to copy the results of cpuid into the brand array directly.
Single Loop for Concatenation:
Calls cpuid with 0x80000002, 0x80000003, and 0x80000004 values and copies each result into different parts of the brand array.
Local Variables:
Uses local arrays regs and brand for storing the register values and the resulting brand string.
Output at End:
The brand string is fully constructed before printing, ensuring that the entire string is output at once.
Summary of Differences
Structure:
The first snippet uses a function with conditional statements and inline assembly directly in C code.
The second snippet uses a macro to encapsulate the cpuid calls, making the code cleaner and more modular.
Memory Management:
The first snippet uses a global array a, while the second snippet uses local arrays regs and brand.
Printing:
The first snippet prints parts of the brand string within the loop.
The second snippet constructs the full brand string first and then prints it.
Efficiency and Readability:
The second snippet is more efficient and readable due to the use of a macro and direct memory copying.
Overall, the second code snippet is more elegant and efficient, with better memory management and cleaner code structure.
Upvotes: 0