eboone20053
eboone20053

Reputation: 65

How to use .if, .else, .elseif for x86 Assembly language

I'm having some trouble with the .if, .else, etc. statements for Assembly.

My code has to reverse a number array in place, and it must work for different data types. I have an if statement to check the type of the data. If it is of type BYTE it will go in the first if statement, if it is WORD it will go through the next one, if it is DWORD it will go to the third one. My problem is that the compiler is throwing errors for the blocks of code that will not be executed. In the current code, i have the array set to byte, and as such it throws errors for the last 2 if statement blocks. Could you please give me some advice on how to fix this.

numbers BYTE 10h, 20h, 30h, 40h, 50h, 60h, 70h, 80h, 90h

L1:

.if (ebx == 1) 
    mov al, numbers[esi]
    xchg al, numbers[edi]
    mov numbers[esi], al 
.elseif (ebx == 2) 
    mov ax, numbers[esi]
    xchg ax, numbers[edi]
    mov numbers[esi], ax 
.else 
    mov eax, numbers[esi]
    xchg eax, numbers[edi]
    mov numbers[esi], eax
.endif
add esi, (type_of_numbers)
sub edi, (type_of_numbers)

Loop L1

Upvotes: 0

Views: 2025

Answers (2)

Peter Cordes
Peter Cordes

Reputation: 364170

.if / .elseif are runtime checks, not assemble-time like C #if / #else. That's why all the blocks have to assemble correctly, even when they don't match the type of numbers.

This looks very inefficient; surely you know the type of numbers at assemble time, like TYPE numbers, and want to use accesses that match that type width?

MASM has assemble-time IF and ELSE (note the lack of a .) for conditional assembly based on constants. That would let you only assemble the block that matches the declaration of numbers and thus wouldn't need any size overrides.

How do you compare variable types in assembly? and see also https://msdn.microsoft.com/en-us/library/4bd8b239.aspx re: if directives in MASM.

So I think you'd do something like like

IF       TYPE numbers == 1
   ... byte swap
ELSEIF   TYPE numbers == 2 
   ... word swap
ELSE
   ... dword swap
ENDIF

I'm not 100% sure you can use TYPE symbol in an IF / ELSEIF directive.


(Of course if you care about efficiency, you wouldn't use xchg [mem], reg because that's an atomic exchange with a full memory barrier: it unfortunately implies a lock prefix.)

Upvotes: 0

eboone20053
eboone20053

Reputation: 65

Add size overrides as necessary (BYTE PTR numbers[esi], WORD PTR ..., DWORD PTR ...). – Michael

Upvotes: 1

Related Questions