GCC-Inline-Assembly-HOWTO
how to write assemble code for gcc.Gcc inline assemble code explaination.GCc-Inline-Assembly-HOWtOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmthe basic format and usage of (GCC)inline assembly functions. To declare inline assembly functions, we usethe keyword asmInline assembly is important primarily because of its ability to operate and make its output visible on cvariables. Because of this capability, asm" works as an interface between the assembly instructions and theC program that contains it3. GCC Assembler SyntaxGCC, the gnu C Compiler for Linux, uses AT&T/UNIX assembly syntax. Here we'll be using At&Tsyntax for assembly coding. dont worry if you are not familiar with at&t syntax, i will teach you. This isquite different from Intel syntax. I shall give the major differences1. Source-Destination OrderingThe direction of the operands in AT&T syntax is opposite to that of Intel. In Intel syntax the firstoperand is the destination, and the second operand is the source whereas in at&t syntax the firstoperand is the source and the second operand is the destination ieOp-code dst src" in Intel syntax changes toOp-code src dst"in at&T syntax2. Register NamingRegister names are prefixed by %o ie, if eax is to be used, write %eax3. Immediate OperandaT&T immediate operands are preceded by'S'. For static"C variables also prefix a$. In Intelsyntax, for hexadecimal constants an is suffixed, instead of that, here we prefix Ox'to the constantSo, for hexadecimal, we first see a$', then 'Ox' and finally the constants4. Operand sizeIn at&t syntax the size of memory operands is determined from the last character of the op-codename Op-code suffixes of,b,,w,, and '1 specify byte(8-bit), word(16-bit), and long(32-bit)memoryreferences. Intel syntax accomplishes this by prefixing memory operands(not the op-codes)with byteptr, 'word ptr,, and 'dword ptrThus, Intel"mov al, byte ptr foo is"movb foo, oal" in at&t syntax5. Memory OperandsIn Intel syntax the base register is enclosed in'I',],where as in at&t they change to '( and)Additionally, in Intel syntax an indirect memory reference is likesection: [ base index*scale disp], which changes tosection: disp(base, index, Scale)in AT&T第3页共14页2018/2/2813:16GCC-Inline-Assembly-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmOne point to bear in mind is that, when a constant is used for disp/scale, 'S shouldnt be prefixedNow we saw some of the major differences between Intel syntax and at& t syntax I've wrote only a few ofthem. For a complete information, refer to gNU Assembler documentations. Now we'll look at someexamples for better understandingIntel codeat&r Codemoveax 1S1,号eaxmovebx, offh与0xffr各ebxint90hintS0x80mov∈bx,eaxmov∈ax3ebI movea,[eC×](ecx),各eaxmoveax, eox+3]mov 13(ebx) eaxmoveax, [eox+20h]mo0x20(ebx),eaxaddeax, [eox+ecx*2h]addl(ebx, eCx,0x2),eax已a∈aⅩlealccebx oesubeax [eox+ecx 4h-2Ch]subl0×20(各eb,8eC,0×4),%eax4. Basic inlineThe format of basic inline assembly is very much straight forward Its basic form isasm("assembly code")dIeExamplasm("movl ecx Beax")i,*moves the contents of ecx to eax *asm ("movb bh (eax)")i/*moves the byte from bh to the memory pointed by eax *You might have noticed that here I've used asm and asm. Both are valid We can use asm if thekeyword asm conflicts with something in our program. If we have more than one instructions, we write oneper line in double quotes, and also suffix a n'and 't to the instruction. This is because gcc sends eachinstruction as a string to as( GAs)and by using the newline/tab we send correctly formatted lines to theassemblerExampleasm ("movl eax, ebx\nt'movl 56, esi\n tiI'movl Becx, $label(edx, %ebx, $4)\n\t'move ah,(ebx)")If in our code we touch(ie, change the contents) some registers and return from asm without fixing thosechanges, something bad is going to happen. This is because gCc have no idea about the changes in theregister contents and this leads us to trouble, especially when compiler makes some optimizations. It willGCC, and it continues like nothing happened. What we can do is either use those instructions having no sits isuppose that some register contains the value of some variable that we might have changed without informin第4页共14页2018/2/2813:16GCC-Inline- Assembl y-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmeffects or fix things when we quit or wait for something to crash. This is where we want some extendedfunctionality. Extended asm provides us with that functionality5. Extended asm。In basic inline assembly, we had only instructions. In extended assembly, we can also specify the operands. Itallows us to specify the input registers, output registers and a list of clobbered registers. It is not mandatory tospecify the registers to use, we can leave that head ache to GCC and that probably fit into gCC's optimizationscheme better. Anyway the basic format isasm( assembler -emplateoutout operands/ optional *input operands/ optional *list of clobbered registers/⊙ ption1*/The assembler template consists of assembly instructions. Each operand is described by an operand- constraintstring followed by the C expression in parentheses. a colon separates the assembler template from the firstoperands within each group. The total number of operands is limited to ten or to the maximum number of foutput operand and another separates the last output operand from the first input, if any. Commas separateoperands in any instruction pattern in the machine description, whichever is greaterIf there are no output operands but there are input operands, you must place two consecutive colonssurrounding the place where the output operands would goExampleasm ("cld\n\tstool:/ no ouput registers x/: c"(count),"a"(fill value),"d"(dest)becx'lbediINow, what does this code do? The above inline fills the fill value count times to the location pointed to bythe register edi. It also says to gcc that, the contents of registers eax and edi arc no longer valid. lct us sccone more example to make things more clearer.nt a-10, basm ("movl l,taxilov1 eax cr"(b)tput:"r"(a, inputaea, clobbered register第5页共14页2018/2/2813:16GCC-Inline-Assembly-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmHere what we did is we made the value of b equal to that ofa using assembly instructions. Some points ofInterest areb"is the output operand, referred to by %00 and"a is the input operand, referred to by."r"is a constraint on the operands. Well see constraints in detail later. For the time being, " r"says toGCC to use any register for storing the operands. output operand constraint should have a constraintmodifier=. And this modifier says that it is the output operand and is write-onlyThere are two %s prefixed to the register name. This helps gcc to distinguish between the operandsand registers. operands have a single as prefixThe clobbered register %eax after the third colon tells GCc that the value of %oeax is to be modifiedinside"asm", so GCC won t use this register to store any other valueWhen the execution of"asm"is complete, "b"will reflect the updated value, as it is specified as an outputoperand. In other words, the change made to"b"inside"asm is supposed to be reflected outside the"asmNow we may look each field in detail5.1 Assembler Template.ormat is like: either each instruction should be enclosed within double quotes, or the entire groupon Gm. TheThe assembler template contains the set of assembly instructions that gets inserted inside the C program. Thedelimiters are newline(n)and semicolon( ) '\n'may be followed by a tab(lt). We know the reason of ainstructions should be within double quotes. Each instruction should also end with a delimiter. The valinewline/tab, right? Operands corresponding to the C expressions are represented by 900, % 1.etc5.2 OperandsC expressions serve as operands for the assembly instructions inside"asm". Each operand is written as first anoperand constraint in double quotes. For output operands there 'll be a constraint modifier also within thequotes and then follows the C expression which stands for the operand. ieconstraint"(C expression) is the general form For output operands an additional modifier will be thereConstraints are primarily used to decide the addressing modes for operands. They are also used in specifyingthe registers to be usedIf we use more than one operand, they are separated by commaIn the assembler template, each operand is referenced by numbers Numbering is done as follows If there area total of n operands(both input and output inclusive), then the first output operand is numbered 0, continuingin increasing order, and the last input operand is numbered n-1. The maximum number of operands is as wesaw in the previous scctionOutput operand expressions must be lvalues. The input operands are not restricted like this. They may beexpressions. The extended asm fcaturc is most often uscd for machinc instructions the compiler itsclf docs notknow as existing - If the output expression cannot be directly addressed (for example, it is a bit-field), ourconstraint must allow a register. In that case, GCC will use the register as the output of the asm and then storethat register contents into the output第6页共14页2018/2/2813:16GCc-Inline-Assembly-HOWtOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmAs stated above, ordinary output operands must be write-only; GCC will assume that the values in theseoperands before the instruction are dead and need not be generated Extended asm also supports input-outputor read-write operandsSo now we concentrate on some examples. We want to multiply a number by 5. For that we use theInstruction leaasm("1ea1(31r81,4),30"I-rl(five times x)Here our input is inx. We didnt specify the register to be used. GCC will choose some register for inputone for output and does what we desired. If we want the input and output to reside in the same register, wecan instruct GCC to do so. Here we use those types of read-write operands. By specifying proper constraints,here we do itasmt("lea1(%0;80,4),90"l=r(five times x)Now the input and output operands are in the same register. But we don' t know which register. Now if wewant to specify that also, there is a wayasm("1ea1(%eCxr是eCxr4),号号eCx"(X)In all the three examples above, we didnt put any register to the clobber list. why In the first two examples,GCC decides the registers and it knows what changes happen. In the last one, we dont have to put ecx on thec lobberlist, gcc knows it goes into x. Therefore, since it can know the value ofecx, it isn t consideredclobbered5. 3 Clobber ListSome instructions clobber some hardware registers. We have to list those registers in the clobber-list, ie thefield after the third :in the asm function. This is to inform gcc that we will use and modify them ourselvesSo gcc will not assume that the values it loads into these registers will be valid We shoudn't list the input andoutput registers in this list. Because, gcc knows that"asm"uses them(because they are specified explicitly asconstraints ). If the instructions use any other registers, implicitly or explicitly(and the registers are not presenteither in input or in the output constraint list), then those registers have to be specified in the clobbered listIf our instruction can alter the condition code register we have to add" ccto the list of clobbered registersIf our instruction modifies memory in an unpredictable fashion, add"memory to the list of clobberedregisters. This will cause GCC to not keep memory values cached in registers across the assembler第7页共14页2018/2/2813:16GCC-Inline-Assembly-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htminstruction. We also have to add the volatile keyword if the memory affected is not listed in the inputs oroutputs of the asmWe can read and write the clobbered registers as many times as we like. Consider the example of multipleinstructions in a template; it assumes the subroutine foo accepts arguments in registers eax and ecxasm movl0,eaxiov11,3各eCx;cal1 foo'r/ no outputs *:g(from),g"(to)neaxITeciL54ⅴ olatile?If you are familiar with kernel sources or some beautiful code like that, you must have seen many functionsdeclared as volatile or volatile which follows an asm or as, i mentioned earlier about thekeywords asm and asm. So what is this volatile?If our assembly statement must execute where we put it ,(i.e. must not be moved out of a loop as anoptimization), put the keyword volatile after asm and before the os. So to keep it from moving, deletingand all. we declare it asasm yolatileUse volatile when we have to be verymuch carefulIf our assembly is just for doing some calculations and doesnt have any side effects, it's better not to use thekeyword volatile. Avoiding it helps gcc in optimizing the code and making it more beautifulIn the section Some Useful Recipes, i have provided many examples for inline asm functions. There we cansee the clobber -list in detail6. More about constraintsBy this time, you might have understood that constraints have got a lot to do with inline assembly but wevesaid little about constraints. Constraints can say whether an operand may be in a register, and which kinds ofregister; whether the operand can be a memory reference, and which kinds of address; whether the operandmay be an immediate constant, and which possible values (ie range of values)it may have.etc6.1 Commonly used constraintsThere are a number of constraints of which only a few are used frequently We'll have a look at thoseconstraints1. Register operand constraint(r)第8页共14页2018/2/2813:16GCC-Inline-Assembly-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmWhen operands are specified using this constraint, they get stored in General Purpose registers(GPr)Take the following exampleasm ("movl 8%eax, 0n": =r"(myval)Here the variable myval is kept in a register, the value in register eax is copied onto that register, andthe value of myval is updated into the memory from this register When the"I"constraint is specified,gcc may keep the variable in any of the available GPrs. to specify the register, you must directlyspecify the register names by using specific register constraints. They areRegister(s)+geax, gax, alebx, bx b18ecx,8C;各C1edx odx odl8esi,号siDedi, odi十2. Memory operand constraint(m)When the operands are in the memory any operations performed on them will occur directly in thememory location, as opposed to register constraints which first store the valuc in a register to bemodified and then write it back to the memory location. But register constraints are usually used onlywhen they are absolutely necessary for an instruction or they significantly speed up the processMemory constraints can be used most efficiently in cases where a C variable needs to be updated inside"asm"and you really don t want to use a register to hold its value For example, the value of idtr isstored in the memory location locasm("sidt 0\n"::"m"(loc))i3. Matching Digit) constraintsIn some cases, a single variable may serve as both the input and the output operand. Such cases may bespccificd in"asm"by using matching constraints("inc10":"=a"(var):"C"(var));We saw similar examples in operands subsection also. In this example for matching constraints, theregister %eax is used as both the input and the output variable var input is read to %eax and updated%eax is stored in var again after increment. 0"here specifies the same constraint as the oth outputvariable. That is, it specifies that the output instance of var should be stored in %eax only. Thisconstraint can be usedo In cases where input is read from a variable or the variable is modified and modification iswritten back to the same variableo In cases where separate instances of input and output operands are not necessaryThe most important effect of using matching restraints is that they lead to the efficient use of availableregisters第9页共14页2018/2/2813:16GCC-Inline-Assembly-HOWTOhttp://ibiblio.org/gferg/ldp/gcc-inline-assembly-howto.htmSome other constraints used are1. "m": A memory operand is allowed, with any kind of address that the machine supports in general2.o: A memory operand is allowed, but only if the address is offsettable. ie, adding a small offset to theaddress gives a valid address3. V": A memory operand that is not offsettable. In other words, anything that would fit the mconstraint but not the constraint4.1: An immediate integer operand (one with constant value)is allowed. This includes symbolicconstants whose values will be known only at assembly time5. n": An immediate integer operand with a known numeric value is allowed many systems cannotsupport assembly-time constants for operands less than a word wide Constraints for these operandsshould use 'n'rather than '6.8": Any register, memory or immediate integer operand is allowed, except for registers that are notgeneral registersFollowing constraints are x86 specific1. I": Register operand constraint, look table given above2. q: Registers a, b, c or d3. I": Constant in range0 to 3 1(for 32-bit shifts)4. Constant in rangc o to 63(for 64-bit shifts)5."K":0xf6."L: Oxffff7. "M": 0, 1, 2, or 3(shifts for lea instruction8. N": Constant in range 0 to 255(for out instruction)9.f: Floating point register10. t": First(top of stack) floating point register1." u: Second floating point register12.A: Specifies the aor d registers. This is primarily useful for 64-bit integer values intended to bereturned with the d' register holding the most significant bits and the a register holding the leastsignificant bits6.2 Constraint modifiersWhile using constraints, for more precise control over the effects of constraints, GCC provides us withconstraint modifiers. Mostly used constraint modifiers are1."=: Means that this operand is write-only for this instruction; the previous value is discarded andreplaced by output data2. "& Means that this operand is an earlyclobber operand, which is modified before the instruction isfinished using the input operands. Therefore, this operand may not lie in a register that is used as aninput operand or as part of any memory address. An input operand can be tied to an earlyclobberoperand if its only use as an input occurs before the early result is writtenThe list and explanation of constraints is by no means complete. Examples can give a betterunderstanding of the use and usage of inline asm. In the next section we'll see some examples, therewe'll find more about clobber-lists and constraints第10页共14页2018/2/2813:16
用户评论