I was looking through an Intel provided reference implementation of RDRAND instruction. The page is Intel Digital Random Number Generator (DRNG) Software Implementation Guide, and the code came from Intel Digital Random Number Generator software code examples.
The following is the relevant portion from Intel. It reads a random value and places it in val, and it sets the carry flag on success.
char rc;
unsigned int val;
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
);
// 1 = success, 0 = underflow
if(rc) {
// use val
...
}
Soory to have to ask. I don't think it was covered in GNU Extended Assembler, and searching for "=qm" is producing spurious hits.
What does the "=qm" mean in the extended assembler?
What you're looking at is an inline assembler constraint. The GCC documentation is at 6.47.3.1 Simple Constraints and 6.47.3.4 Constraints for Particular Machines under x86 family section. This one (=qm) combines three flags which indicate:
=: The operand is write-only - its previous value is not relevant.
q: The operand must be in register a, b, c, or d (it cannot be in esi, for instance).
m: The operand may be placed in memory.
qm probably means 1 byte 8 bit mem
=qm will be valid constraint for storing 1 byte result
See what setc wants
http://web.itu.edu.tr/~aydineb/index_files/instr/setc.html
reg8 and mem8
as we know only eax , ebx edx ecx .. a,b,c,d registers that q refer can be used cause they can accessed with low byte al dl cl ...With combining qm we are getting mem8 . m meant memory. Thats what I meant
Wow that stumped me at first but I searched around a bit and found out that it is a reference to the model of the processor this peice of code is meant for.
Spicically I read that it is for the i7 Quadcore.
Is that where you got this code from?
It is a simple value indicator for a variable syntax.
Related
I am working on a nice tool, which requires the atomic swap of two different 64-bit values. On the amd64 architecture it is possible with the XCHGQ instruction (see here in doc, warning: it is a long pdf).
Correspondingly, gcc has some atomic builtins which would ideally do the same, as it is visible for example here.
Using these 2 docs I produced the following simple C function, for the atomic swapping of two, 64-bit values:
void theExchange(u64* a, u64* b) {
__atomic_exchange(a, b, b, __ATOMIC_SEQ_CST);
};
(Btw, it wasn't really clear to me, why needs an "atomic exchange" 3 operands.)
It was to me a little bit fishy, that the gcc __atomic_exchange macro uses 3 operands, so I tested its asm output. I compiled this with a gcc -O6 -masm=intel -S and I've got the following output:
.LHOTB0:
.p2align 4,,15
.globl theExchange
.type theExchange, #function
theExchange:
.LFB16:
.cfi_startproc
mov rax, QWORD PTR [rsi]
xchg rax, QWORD PTR [rdi] /* WTF? */
mov QWORD PTR [rsi], rax
ret
.cfi_endproc
.LFE16:
.size theExchange, .-theExchange
.section .text.unlikely
As we can see, the result function contains not only a single data move, but three different data movements. Thus, as I understood this asm code, this function won't be really atomic.
How is it possible? Maybe I misunderstood some of the docs? I admit, the gcc builtin doc wasn't really clear to me.
This is the generic version of __atomic_exchange_n (type *ptr, type val, int memorder) where only the exchange operation on ptr is atomic, the reading of val is not. In the generic version, val is accessed via pointer, but the atomicity still does not apply to it. The pointer is so that it will work with multiple sizes, when the compiler has to call an external helper:
The four non-arithmetic functions (load, store, exchange, and
compare_exchange) all have a generic version as well. This generic
version works on any data type. It uses the lock-free built-in
function if the specific data type size makes that possible;
otherwise, an external call is left to be resolved at run time. This
external call is the same format with the addition of a ‘size_t’
parameter inserted as the first parameter indicating the size of the
object being pointed to. All objects must be the same size.
I have the inline assembly code:
#define read_msr(index, buf) asm volatile ("rdmsr" : "=d"(buf[1]), "=a"(buf[0]) : "c"(index))
The code using this macro:
u32 buf[2];
read_msr(0x173, buf);
I found the disassembly is (using gnu toolchain):
mov eax,0x173
mov ecx,eax
rdmsr
mov DWORD PTR [rbp-0xc],edx
mov DWORD PTR [rbp-0x10],eax
The question is that 0x173 is less than 0xffff, why gcc does not use mov cx, 0x173? Will the gcc analysis the following instruction rdmsr? Will the gcc always know the correct register size?
It depends on the size of the value or variable passed.
If you pass a "short int" it will set "cx" and read the data from "ax" and "dx" (if buf is a short int, too).
For char it would access "cl" and so on.
So "c" refers to the "ecx" register, but this is accessed with "ecx", "cx", or "cl" depending on the size of the access, which I think makes sense.
To test you can try passing (unsigned short)0x173, it should change the code.
There is no analysis of the inline assembly (in fact it is after text substitution direclty copied to the output assembly, including syntax errors). Also there is no default register size, depending on whether you have a 32 or 64 bit target. This would be way to limiting.
I think the answer is because the current default data size is 32-bit. In 64-bit long mode, the default data size is also 32-bit, unless you use "rex.w" prefix.
Intel specifies the RDMSR instruction as using (all of) ECX to determine the model specific register. That being the case, and apparently as specified by your macro, GCC has every reason to load your constant into the full ECX.
So the question about why it doesn't load CX seems completely inappropriate. It looks like GCC is generating the right code.
(You didn't ask why it stages the load of ECX inefficiently by using EAX; I don't know the answer to that).
I'm using a MacBook Pro with an Intel Core 2 Duo processor at 2.53 GHz, but I was told Mac users must follow AT&T syntax (which adds to my confusion since I am running Intel) and x86 (not sure what this means exactly).
So I need to get into assembly but am finding it very hard to even begin. Searches online show assembly code that varies greatly in syntax and I can't find any resources that explain basic assembly how-tos. I keep reading about registers and a stack but don't understand how to look at this. Can anyone explain/point me in the right direction? Take, for example, this code which is the only code I found to work:
.data
_mystring: .ascii "Hello World\n\0" #C expects strings to terminate with a 0.
.text
.globl _foo
_foo:
push %ebp
mov %esp,%ebp
pushl $_mystring
call _myprint
add $4,%esp
pop %ebp
ret
Very simple but what is it saying? I am having a confusing time understanding how this code does what it does. I know Java, PHP, and C, among other languages, but this, the steps and syntax of it, isn't clear to me. Here's the main file to go with it:
#include <stdio.h>
void foo();
void myprint(char *s)
{printf("%s", s);}
main()
{foo();}
Also, there's this which just multiplies numbers:
.data
.globl _cntr
_cntr: .long 0
.globl _prod
_prod: .long 0
.globl _x
_x: .long 0
.globl _y
_y: .long 0
.globl _mask
_mask: .long 1
.globl _multiply
multiply:
push %ebp
mov %ebp,%esp
mov $0,%eax
mov _x,%ebx
mov _y,%edx
LOOP:
cmp $0,%ebx
je DONE
mov %ebx,%ecx
and $1,%ecx
cmp $1,%ecx
jne LOOPC
add %edx,%eax
LOOPC:
shr $1,%ebx
shl $1,%edx
jmp LOOP
DONE:
pop %ebp
ret
and the main.c to go with it:
#include <stdio.h>
extern int multiply();
extern int x, y;
int main()
{
x = 34;
y = 47;
printf("%d * %d = %d\n", x, y, multiply());
}
And finally three small questions:
What is the difference between .s and .h file names (I have both a main.c and main.h, which one is for what)?
And why does assembly need a main.c to go with it/how does it call it?
Can anyone recommend a good assembly IDE like Eclipse is for Java or PHP
Thanks to whomever answers (this is actually my first post on this site), I've been trying to figure this out for a few days and every resource I have read just doesn't explain the assembly logic to me. It says what .data or .text does but only someone who knows how to "think assembly" would understand what they mean?
Also, if anyone is around New York City and feels very comfortable with Assembly and C I would love some private lessons. I feel there is a lot of potential with this language and would love to learn it.
Assembly language is a category of programming languages which are closely tied to CPU architectures. Traditionally, there is a one-to-one correspondence between each assembly instruction and the resulting CPU instruction.
There are also assembly pseudo-instructions which do not correspond to CPU instruction, but instead affect the assembler or the generated code. .data and .text are pseudo-instructions.
Historically, each CPU manufacturer implemented an assembly language as defined by their assembler, a source code translation utility. There have been thousands of specific assembly languages defined.
In modern times, it has been recognized that each assembly language shares a lot of common features, particularly with respect to pseudo-instructions. The GNU compiler collection (GCC) supports essentially every CPU architecture, so it has evolved generic assembly features.
x86 refers to the Intel 8086 family (8088, 8086, 8087, 80186, 80286, 80386, 80486, 80586 aka Pentium, 80686 aka Pentium II, etc.)
AT&T syntax is a notation style used by many assembly language architectures. A major feature is that instruction operands are written in the order from, to as was common historically. Intel syntax uses to, from operands. There are other differences as well.
As for your many questions, here are some resources which will 1) overwhelm you, and 2) eventually provide all your answers:
assembly language overview
tutorials and resources
x86 instruction summary
comprehensive x86 architecture reference
Ordinarily, an introductory assembly language programming class is a full semester with plenty of hands-on work. It assumes you are familiar with the basics of computer architecture. It is reasonable to expect that understanding the above material will take 300-500 hours. Good luck!
I never thought I'd be posting an assembly question. :-)
In GCC, there is an extended version of the asm function. This function can take four parameters: assembly-code, output-list, input-list and overwrite-list.
My question is, are the registers in the overwrite-list zeroed out? What happens to the values that were previously in there (from other code executing).
Update: In considering my answers thus far (thank you!), I want to add that though a register is listed in the clobber-list, it (in my instance) is being used in a pop (popl) command. There is no other reference.
No, they are not zeroed out. The purpose of the overwrite list (more commonly called the clobber list) is to inform GCC that, as a result of the asm instructions the register(s) listed in the clobber list will be modified, and so the compiler should preserve any which are currently live.
For example, on x86 the cpuid instruction returns information in four parts using four fixed registers: %eax, %ebx, %ecx and %edx, based on the input value of %eax. If we were only interested in the result in %eax and %ebx, then we might (naively) write:
int input_res1 = 0; // also used for first part of result
int res2;
__asm__("cpuid" : "+a"(input_res1), "=b"(res2) );
This would get the first and second parts of the result in C variables input_res1 and res2; however if GCC was using %ecx and %edx to hold other data; they would be overwritten by the cpuid instruction without gcc knowing. To prevent this; we use the clobber list:
int input_res1 = 0; // also used for first part of result
int res2;
__asm__("cpuid" : "+a"(input_res1), "=b"(res2)
: : "%ecx", "%edx" );
As we have told GCC that %ecx and %edx will be overwritten by this asm call, it can handle the situation correctly - either by not using %ecx or %edx, or by saving their values to the stack before the asm function and restoring after.
Update:
With regards to your second question (why you are seeing a register listed in the clobber list for a popl instruction) - assuming your asm looks something like:
__asm__("popl %eax" : : : "%eax" );
Then the code here is popping an item off the stack, however it doesn't care about the actual value - it's probably just keeping the stack balanced, or the value isn't needed in this code path. By writing this way, as opposed to:
int trash // don't ever use this.
__asm__("popl %0" : "=r"(trash));
You don't have to explicitly create a temporary variable to hold the unwanted value. Admittedly in this case there isn't a huge difference between the two, but the version with the clobber makes it clear that you don't care about the value from the stack.
If by "zeroed out" you mean "the values in the registers are replaced with 0's to prevent me from knowing what some other function was doing" then no, the registers are not zeroed out before use. But it shouldn't matter because you're telling GCC you plan to store information there, not that you want to read information that's currently there.
You give this information to GCC so that (reading the documentation) "you need not guess which registers or memory locations will contain the data you want to use" when you're finished with the assembly code (eg., you don't have to remember if the data will be in the stack register, or some other register).
GCC needs a lot of help for assembly code because "The compiler ... does not parse the assembler instruction template and does not know what it means or even whether it is valid assembler input. The extended asm feature is most often used for machine instructions the compiler itself does not know exist."
Update
GCC is designed as a multi-pass compiler. Many of the passes are in fact entirely different programs. A set of programs forming "the compiler" translate your source from C, C++, Ada, Java, etc. into assembly code. Then a separate program (gas, for GNU Assembler) takes that assembly code and turns it into a binary (and then ld and collect2 do more things to the binary). Assembly blocks exist to pass text directly to gas, and the clobber-list (and input list) exist so that the compiler can do whatever set up is needed to pass information between the C, C++, Ada, Java, etc. side of things and the gas side of things, and to guarantee that any important information currently in registers can be protected from the assembly block by copying it to memory before the assembly block runs (and copying back from memory afterward).
The alternative would be to save and restore every register for every assembly code block. On a RISC machine with a large number of registers that could get expensive (the Itanium has 128 general registers, another 128 floating point registers and 64 1-bit registers, for instance).
It's been a while since I've written any assembly code. And I have much more experience using GCC's named registers feature than doing things with specific registers. So, looking at an example:
#include <stdio.h>
long foo(long l)
{
long result;
asm (
"movl %[l], %[reg];"
"incl %[reg];"
: [reg] "=r" (result)
: [l] "r" (l)
);
return result;
}
int main(int argc, char** argv)
{
printf("%ld\n", foo(5L));
}
I have asked for an output register, which I will call reg inside the assembly code, and that GCC will automatically copy to the result variable on completion. There is no need to give this variable different names in C code vs assembly code; I only did it to show that it is possible. Whichever physical register GCC decides to use -- whether it's %%eax, %%ebx, %%ecx, etc. -- GCC will take care of copying any important data from that register into memory when I enter the assembly block so that I have full use of that register until the end of the assembly block.
I have also asked for an input register, which I will call l both in C and in assembly. GCC promises that whatever physical register it decides to give me will have the value currently in the C variable l when I enter the assembly block. GCC will also do any needed recordkeeping to protect any data that happens to be in that register before I enter the assembly block.
What if I add a line to the assembly code? Say:
"addl %[reg], %%ecx;"
Since the compiler part of GCC doesn't check the assembly code it won't have protected the data in %%ecx. If I'm lucky, %%ecx may happen to be one of the registers GCC decided to use for %[reg] or %[l]. If I'm not lucky, I will have "mysteriously" changed a value in some other part of my program.
I suspect the overwrite list is just to give GCC a hint not to store anything of value in these registers across the ASM call; since GCC doesn't analyze what ASM you're giving it, and certain instructions have side-effects that touch other registers not explicitly named in the code, this is the way to tell GCC about it.
I am new to assembly language. It seems that gcc doesn't have _bittestandset function in intrin.h like MSVC does, so I implemented a new one. This one works fine in linux, but it goes wrong with mingw in winVista machine, the code is:
inline unsigned char _bittestandset(unsigned long * a, unsigned long b)
{
__asm__ ( "bts %1, %[b]"
: "=g"(*a)
: [b]"Ir"(b), "g"(*a) );
return 0;
}
Could you give some further explanation what's not working? Maybe a simple example of the usage or so. It's hard to guess what's wrong with the code..
One thing that looks cheesy so far: You execute a bit-test opcode but ignore the result. The bit that you test (and set) ends up in the carry flag after the opcode.
If you want to get the result you need an additional instruction to get the carry flag into some other output register. (SBB EAX, EAX or something like that).
Otherwise - if you don't need the result - it's much cheaper to replace the BTS instruction with three simpler assembler opcodes:
Something along these lines:
; bit-index in cl
; Value in ebx
; eax used as a temporary (trashed)
mov eax, 1
shl eax, cl
or ebx, eax
Since I don't have mingw with your exact version running a assembly-output of a simple testcase could give us some clue what's going wrong.
DON'T use the BTS instruction. It's horribly slow. A better way would be to implement it using simple shift+or. And as a bonus, you can do it without any assembly, in pure, portable C++.