asm() function in C [duplicate] - c

This question already has answers here:
What is the colon in the c language between two strings?
(1 answer)
What is the difference between 'asm', '__asm' and '__asm__'?
(4 answers)
Using inline assembly with serialization instructions
(1 answer)
CPUID implementations in C++
(3 answers)
How to use CPUID instruction to get x86 CPU features correctly? [duplicate]
(1 answer)
Closed 10 hours ago.
I'm working with some low-level C code and I don't quite understand what's going on here:
/* Description of the current CPU. */
struct cpuid { unsigned eax, ebx, ecx, edx; };
/* Return information about the CPU. See <http://wiki.osdev.org/CPUID>. */
static struct cpuid
cpuid (unsigned int leaf, unsigned int subleaf)
{
struct cpuid result;
asm ("cpuid"
: "=a" (result.eax), "=b" (result.ebx),
"=c" (result.ecx), "=d" (result.edx)
: "a" (leaf), "c" (subleaf));
return result;
}
I've tried looking for information on the asm() function, including that wiki page, but I'm still struggling in deciphering the code. I understand that the : syntax is an old-school, deprecated way to initialize structs, but I don't really see how it's working here.
edit:
my question is specifically about what this snippet of code is doing, not the syntax or any of that. just this section and what's going on.

Related

Using inline assembly to copy data from one array to another in C [duplicate]

This question already has answers here:
How to prevent gcc optimization breaking rep movsb code? [duplicate]
(1 answer)
Enhanced REP MOVSB for memcpy
(6 answers)
How to access C variable for inline assembly manipulation?
(2 answers)
How do I access local C variable in arm inline assembly?
(2 answers)
Looping over arrays with inline assembly
(3 answers)
Closed 1 year ago.
I'm trying to copy data from one array to another using inline assembly in C by using the rep movsd, my code currently looks like this:
#include<stdio.h>
int main(){
int v1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int v2[10];
asm ("mov %edi, v2\n"
"mov %esi, v1\n"
"mov %ecx, 40\n"
"rep movsd"
);
for(int i=0;i<10;i++){
printf("%d ", v2[i]);
}
printf("\n");
return 0;
}
But I keep getting an error saying that I can't use v2 and v1 in the following way:
Undefined symbol "v2" can't be used to make a PIE object
I couldn't find the correct syntax to add C pointers to the inline assembly.
I'm using the following version of gcc:
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

Get pid from c inline extended asm [duplicate]

This question already has answers here:
What does a double-percent sign (%%) do in gcc inline assembly?
(3 answers)
What is r() and double percent %% in GCC inline assembly language?
(4 answers)
Inline assembly : register referencing conventions
(1 answer)
Closed 2 years ago.
I want to get the process id of my test C program but I don't understand what I'm doing wrong with my inline assembly code.
When I write
pid_t pid;
asm volatile ( // Basic asm statement (never use)
"movl $20, %eax"
"int $0x80"
);
// editor's note: this is unsafe, never do it this way.
// You don't tell the compiler EAX is overwritten, among other problems.
asm volatile ( // Extended asm statement
"movl %%eax,%0"
: "=r"(pid)
);
the variable pid gets exactly the value I expect. However I can't get this working together in an extended assembly call as written here:
https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
If I try something like this
asm volatile (
"movl $20, %eax"
"int $0x80"
"movl %%eax,%0"
: "=r"(pid)
);
GCC (run by Visual Studio Code) gives me the error message:
error: invalid 'asm': operand number missing after %-letter
So why can this work in two separate calls but the moment I call it as extended asm it doesn't anymore?

Execution of volatile instruction [duplicate]

This question already has answers here:
The difference between asm, asm volatile and clobbering memory
(3 answers)
What does __asm__ __volatile__ do in C?
(3 answers)
Closed 5 years ago.
int __attribute__ ((noinline)) mySystemCall (uint32 Exception, uint32 Parameter)
{
#ifdef PROCESSORX
__asm__ volatile ("sc")
#else
__asm__ __volatile__ ("mov R0, %0; mov R1, %1; svc 0x0 " : : "r" (Exception), "r" (Parameter));
}
How does the compiler translate the instruction (asm volatile ("sc"))?
Why are some arguments passed as strings and some are not (ex:
__asm__ __volatile__("rdtsc": "=a" (a), "=d" (d) ))
Inline assembly isn't specified by the C standard. I assume this is code for gcc and compatible, then you should have a look at the manual.
As for your specific questions:
How does the compiler translate the instruction (asm volatile ("sc"))?
The volatile in this context instructs the compiler that the assembler snippet must be included, even if the compiler can't see a reason it's actually needed for the behavior of the program. Whatever comes in the first string parameter is literal assembly code of the target platform.
Why are some arguments passed as strings and some are not
It's just part of the syntax, refer to the manual I listed above. Inline assembly can "bind" input and output parameters to C variables and also tell the compiler which registers are "clobbered" by the assembly snippet (among other things).
Inline assemblers have to bridge the gap between C and assembly so in addition to ones assembly code, one needs to give details of how they interact. The first item in the GCC assembly template is the actual assembly, the other items include assigning input variables, output variables and clobbers (registers/memory) that the assembly may clobber so C need to steer clear of. The full details may be found: here.

How can I include inline assembly code in a C source code? [duplicate]

This question already has answers here:
using assembly code inside Objective c program (Xcode)
(1 answer)
How do I do inline assembly on the IPhone?
(5 answers)
Closed 7 years ago.
This question is for educational purpose only. I want to know the way to include an inline assembly code (I am using Xcode, with i7 Intel processor) in a C source code.
For example:
main(){
int a = 2, b = 3, c = 0;
/*
*Sum c = a + b implemented using assembly
*/
{
mov eax, ??? (a)
mov ebx, ??? (b)
bla bla bla...
}
return 0;
}
Read the clang manuals (clang is the compiler used by xcode).
E.g., see here: http://clang.llvm.org/compatibility.html#inline-asm

Can you inline LLVM bitcode in C compiled by Clang? [duplicate]

This question already has an answer here:
How to embed LLVM assembly or intrinsics in C program with Clang?
(1 answer)
Closed 9 years ago.
I was looking enviously at the ability to put inline assembler in code compiled by GCC, and I'm wondering if you could do something similar with Clang? For example is there some way I could complete the definition of a function with LLVM assembler:
int add_two_ints(int a, int b) {
/*
* some bitcode stuff goes here to add
* the ints and return the result
*/
}
Any references, or code to complete the example above would be great.
clang supports inline assembly, including GCC's extension where you declare input, output, and clobbered registers:
int add_two_ints(int a, int b) {
int result;
asm( "addl %1, %2;"
"movl %2, %0;"
: "=r"(result)
: "r"(a), "r"(b)
:);
return result;
}
Clang also has experimental support for Microsoft's __asm { } syntax and intel style assembly.
It does not have any support for including LLVM-IR in C or C++ source. Such a feature would largely be just a novelty as inline assembly is typically for accessing special instructions and LLVM-IR doesn't enable that.

Resources