Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Inline Assembly Help Please!

Status
Not open for further replies.

StockBreak

Programmer
Jun 26, 2007
1
0
0
Hi, I recently started programming with inline assembly (I use Visual C++), but I have found a bug that I cannot solve.
Why does it give an error?

// C language
unsigned char array[] = {1, 2, 3, 4, 5, 6, 7};

// Assembly
__asm {
XOR CL,CL

MOV AL,array[CL]
}

The error is -> "error C2403: 'CL' : register must be base/index in 'second operand'".

I tested it many times and I found that the only way to make it work is to use ECX register as index! Why?
If I use ANY OTHER register it will not compile (as above) or it will give a Fatal Error if I use another EXX register (as EAX or EBX).
The problem is that on my program I have a "nested for loop" and so I can't use just 1 counter (ECX), but I need 2 of them and they must be BYTE register (as CL/CH) because the array variable is a char. Any idea?

Thank you very much!
Luke

P.S: any better idea on how to write effective inline nested loop?
 
I'm not totally sure, but you might try to PUSH ECX, go through the inner counter, using ECX, then store ECX in any other register, and POP ECX to return to your previous count.
 
Just so I am sure I am reading this correctly, you want to move the byte at Array[CX] into AL, correct? if so try this:

...
xor bx, bx; zero out bx register
mov AL, array + bx; move byte at array[bx] to al
...

as for your second question;

...
mov cx,OuterLoopCount
OuterLoop:
push cx
; do outer loop stuff
mov cx, InnerLoopCount
InnerLoop:
; do inner loop stuff
...
Loop InnerLoop
; do more outer loop stuff
pop cx
loop OuterLoop
...

Works real nice for me

Notes on looping; you need to use the entire cx register if in Real (16 bit) mode or ecx in Protected (32 bit) mode because looping will not end until the appropiate register reaches zero; if you have something you want to save in CH for example, the loop command will continue to decrement/increment thru CH also, thereby destroying what you wanted to save, which is why I used push cx to save the outer loop variable and pop cx to restore it. You could just as easily use another reg to store CX, but then you run the risk of accidently overwriting it.

90% of all questions can be answer by the Help file! Try it and be amazed.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top