views:

314

answers:

2

My Code

const int howmany = 5046;
char buffer[howmany];
    asm("lea     buffer,%esi"); //Get the address of buffer
    asm("mov     howmany,%ebx");         //Set the loop number
    asm("buf_loop:");                      //Lable for beginning of loop
    asm("movb     (%esi),%al");             //Copy buffer[x] to al
    asm("inc     %esi");                   //Increment buffer address
    asm("dec     %ebx");                   //Decrement loop count
    asm("jnz     buf_loop");              //jump to buf_loop if(ebx>0)

My Problem

I am using the gcc compiler. For some reason my buffer/howmany variables are undefined in the eyes of my asm. I'm not sure why. I just want to move the beginning address of my buffer array into the esi register, loop it 'howmany' times while copying each element to the al register.

+7  A: 

Are you using the inline assembler in gcc? (If not, in what other C++ compiler, exactly?)

If gcc, see the details here, and in particular this example:

    asm ("leal (%1,%1,4), %0"
         : "=r" (five_times_x)
         : "r" (x) 
         );

%0 and %1 are referring to the C-level variables, and they're listed specifically as the second (for outputs) and third (for inputs) parameters to asm. In your example you have only "inputs" so you'd have an empty second operand (traditionally one uses a comment after that colon, such as /* no output registers */, to indicate that more explicitly).

Alex Martelli
I have no grasp of the watcom nonsense...I've read quite a bit and still can't quite grasp it...I would think I should be able to simply move the address of my buffer into a register.
kelton52
What "watcom"? I'm talking about gcc -- in THAT compiler (which is very widespread, you know) you have to use %0, %1 and so on in the assembly code proper, then connect them to input and output C expressions in the second and third args of `asm` -- and that's all there is to it. Feel free to disapprove of gcc's design (and to contribute changes to it, since it's open source), but I'm telling you how it DOES work. Your example code doesn't follow these rules, which is why it isn't working (if gcc's your compiler;-).
Alex Martelli
+2  A: 

The part that declares an array like that

int howmany = 5046;
char buffer[howmany];

is not valid C++. In C++ it is impossible to declare an array that has "variable" or run-time size. In C++ array declarations the size is always a compile-time constant.

If your compiler allows this array declaration, it means that it implements it as an extension. In that case you have to do your own research to figure out how it implements such a run-time sized array internally. I would guess that internally buffer will be implemented as a pointer, not as a true array. If my guess is correct and it is really a pointer, then the proper way to load the address of the array into esi might be

mov buffer,%esi

and not a lea, as in your code. lea will only work with "normal" compile-time sized arrays, but not with run-time sized arrays.

Another question is whether you really need a run-time sized array in your code. Could it be that you just made it so by mistake? If you simply change the howmany declaration to

const int howmany = 5046;

the array will turn into an "normal" C++ array and your code might start working as is (i.e. with lea).

AndreyT
I forgot to add const in my example, so that isn't an issue. Thanks anyhow though.
kelton52