Quantcast
Viewing all articles
Browse latest Browse all 2

How to use a variable offset in inline assembly?

The overall problem I am trying to solve, is to call printf, while fetching its format string and arguments from a raw buffer. So far, the solution that seems to be working the best is through the use of inline assembly as a way to pass the mixed typing variadic arguments to the function.

Currently we have chars and ints working flawlessly, and floats/doubles working up until we need to pass them on the stack. (Passing through xmm0 - xmm7 works flawlessly for us). The goal here is to push these floating point values to the stack once xmm0-xmm7 have all been used. These values would then be used in the subsequent call to printf. The way we handle this for the chars and ints is to push them onto the stack just by simply using the push instruction, which the call to printf is able to use just fine, but since that instruction doesn't work for floating point values we have to manually 'push' it onto the stack with the method below. I realize that this is very likely to be the wrong way to handle this, but we haven't been able to figure a way out of doing it this way.

Currently our solution to passing more than eight floating point values on the stack requires us to know the offset of the argument that is being passed to our printf call. In this case the offsets correspond to 8 byte increments. The 9th argument is to be loaded into (%rsp), the 10th into 0x8(%rsp) the 11th into 0x10(%rsp) the 12th into 0x18(%rsp) with the rest of the arguments continuing this trend.

My goal with this "variable offset" is to just reduce the amount of repeated code that handles the incremented offset. Currently it just checks which argument is being processed, and jumps to the hardcoded constant offset. But this has led to a lot of duplicated code, which I was hoping to clean up.

Below is a small snippet of what we are doing currently to move one of the arguments into its appropriate place for the call to printf to access the argument.

double myDouble = 1.23;asm volatile ("movsd %0, 0x8(%%rsp)" #The 0x8 is the offset we are hoping to pass in:: "m" (myDouble));

I am looking for a way to store this offset (0x8, 0x10, 0x18,...) in a variable that can be incremented by eight as I process the arguments, though I now fear that this will break once we start mixing in more mixed typed values that are pushed onto the stack.

Any guidance would be greatly appreciated!


Viewing all articles
Browse latest Browse all 2

Trending Articles