GCC Inline Assembly Multiplication?

The problem I'm seeing is that the C variable a is set to 0 after the multiplication (or 1 on an overflow. ) I don't understand why a would be changed at all by anything I'm doing here. It's not even on the list of output variables, so why is my assembly routine affecting the value of a?

Mul %%bl multiplies AL (8 bits) by BL (8 bits), placing the result in AX (16 bits) Note that AL and AX are not separate registers: AL is just the bottom 8 bits of AX movw %%ax, %0 stores AX (16 bits) to the address of be which is a uint8_t So this instruction is also overwriting the next byte in memory with the top 8 bits of the result. In this case, that byte happens to be where the value of a is stored (which explains why a is overwritten with 0 when it doesn't overflow, and 1 when it does) You need to replace that with movb %%al, %0 to do just a byte store of the bottom 8 bits of the result I think I need to inform GCC that I used the AL and BL registers, but what about the AX register? It's used implicitly to store the product of two 8-bit integers, so do I need to include it in the list of clobbered registers?

Yes - you should tell GCC about any register that you change the value of (and, as nategoose pointed out in another answer, you should probably tell it that you're changing the flags as well). So the clobber list here should be %ax", "%bl", "cc (AX includes AL, so you don't need to mention AL explicitly).

The problem I'm seeing is that the C variable a is set to 0 after the multiplication (or 1 on an overflow. ) I don't understand why a would be changed at all by anything I'm doing here. It's not even on the list of output variables, so why is my assembly routine affecting the value of a?

Mul %%bl multiplies AL (8 bits) by BL (8 bits), placing the result in AX (16 bits). Note that AL and AX are not separate registers: AL is just the bottom 8 bits of AX. Movw %%ax, %0 stores AX (16 bits) to the address of b... which is a uint8_t.

So this instruction is also overwriting the next byte in memory with the top 8 bits of the result. In this case, that byte happens to be where the value of a is stored (which explains why a is overwritten with 0 when it doesn't overflow, and 1 when it does). You need to replace that with movb %%al, %0, to do just a byte store of the bottom 8 bits of the result.

I think I need to inform GCC that I used the AL and BL registers, but what about the AX register? It's used implicitly to store the product of two 8-bit integers, so do I need to include it in the list of clobbered registers? Yes - you should tell GCC about any register that you change the value of (and, as nategoose pointed out in another answer, you should probably tell it that you're changing the flags as well).

So the clobber list here should be "%ax", "%bl", "cc" (AX includes AL, so you don't need to mention AL explicitly).

You should compile your code with the -S option and have a look at the *. S file. All of your assembly is on the same line separated by semicolons, and I believe that semicolons begin comments in gnu assembler.

You'll need to add "\n" (or better yet "\n\t") to the ends of all of your assembly instructions. You might also want to add "cc" to the clobber list. Additionally, GCC has a way to specify that input is both an input and an output to assembly which you might be interested in.

Also, it is probably best if let GCC decide where the inputs to this are rather than forcing them be in memory. I seem to remember that GCC's inline assembly has a constraint on x86 that means "either in a register or in memory" that can be used for circumstances where it doesn't matter, but you probably shouldn't have many "mov" instructions at the beginning and ends of your inline assembly because one of GCC's biggest jobs is figuring out the best sets of move instructions to put between actual calculating instructions. For instance, in your code the best thing for GCC to do would be to just store the constants 10 and 25 in the registers that you are using to begin with.

1 The GNU assembler syntax changes depending on the target. Semicolons work just fine as separators for x86, but maybe not elsewhere. – Matthew Slattery Oct 7 '10 at 22:17.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions