News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

use of .if statemet, among other questions

Started by sportskid300, November 28, 2007, 01:58:15 AM

Previous topic - Next topic

sportskid300

OK, thanks for the help with the uval and mul/div operands!
Now, I'm having a bit of trouble with .if
I have it running now, but it seems that
.if str1 == 1
jmp A
.elseif str1 != 2
jmp B
.elseif str1 != 3
jmp C
.else
jmp D
.endif

Has some problems.
First, to make it work, I had to make it jumpto B if str1 was 3 and to jump to C if str1 was 2.
Also, for any input with the exception of 1, 2, and 3, it returned values of 3, because jumping to B continued happening.
So, from the problems with the above code, I modified it to a lengthier, working code:
cmp str1, 3
ja wrong
cmp str1, 1
jb wrong
.if str1 == 1
jmp A
.elseif str1 != 3
jmp B
.elseif str1 != 2
jmp C
.endif

Any use of .else was useless, as it continually returned the value 3.

If anyone could explain or help me, I'd appreciate it a lot.

By the way, I attached my full work in progress both in .exe and in .asm

If any moderator happens to see this, may I suggest aloowing .rar extrensions as well?
I understand the caution for uploading .exe, but I feel .asm, .txt, and ESPECIALLY .rar are just as safe as .zip.


[attachment deleted by admin]
I can't wait to make windows...

MichaelW

uval is a macro that converts a decimal string to an unsigned integer value:

uval MACRO lpstring       ; string to unsigned 32 bit integer
    invoke atodw, reparg(lpstring)
    EXITM <eax>
ENDM

You pass it the address of a null-terminated decimal string and it returns the value as an unsigned integer in eax:

.data
  decimalstring db "12345",0
.code
  mov ecx, uval(ADDR decimalstring)
  ; ecx now contains the value 12345.

For information on the MASM32 macros, see \masm32\help\hlhelp.hlp

For basic information on the integer multiply and divide instructions see \masm32\help\opcodes.hlp, or for the details see the Intel instruction set reference manuals available here.
eschew obfuscation

Tedd

"add num1,num2" will not work because both num1 and num2 are memory addresses. x86 instructions only allow you to operate on one memory address at a time (in general.) So you need to get one of those into a register first, and then add it on to the other - e.g. "mov eax,num2; add num1,eax"
This applies in general to all other situations where you need to use two variables.


MUL :

;eax * ecx
mov eax,<32-bit_integer_to_multiply>
mov ecx,<32-bit_integer_to_multiply_by>
mul ecx
;;result is now in edx:eax -- high 32 bits are in edx, low in eax - giving a 64-bit result

;mul always operates on eax and the value you give it (which can be a memory address)
;and the result is stored in edx:eax


DIV :

;edx:eax / ecx
mov edx,<high_32-bits_of_64-bit_integer_to_divide>
mov eax,<low_32-bits_of_64-bit_integer_to_divide>
mov ecx,<32-bit_integer_to_divide_by>
mul ecx
;;result is now in eax
;;the remainder is also stored in edx (so you get both in one operation)

;div always operates on edx:eax and the value you give it (which can be a memory address)
;the result is stored in eax, and the remainder in edx


mul and div are actually unsigned, which means they treat all numbers as positive.

imul and idiv can handle negative numbers, but are the same as mul and idiv in usage.
With the exception that imul has 2 and 3 operand versions, which allow you to choose which registers to use (so you're not always limited to eax and edx:eax)
No snowflake in an avalanche feels responsible.

sportskid300

Thanks for the explanations!
The uval makes sense, but I'm having problems with the div and multiply results.
I don't get the highend-lowend concept.
If I wanted to multiply 5 x 4, and then store it into a variable, say num20, how would I do that?
Thanks in advance
I can't wait to make windows...

ChrisLeslie

Hi sportskid300

I'm just cranking up my rusty asm 'skills'.... :boohoo:
To multiply integers 4 by 5:

Move a value of 5 to eax.
Move a value of 4 to ecx.
Execute mul (or imul) using ecx.
The result is stored in eax as a binary number of value 20. No need for high or low 32 bit in this case.
Move eax to your dd memory variable of 'num20' if you wish.
Convert eax, or num20, to an ascii string, using 'dwtoa' or something similar if you want to display it as a decimal number.

Cheers - Chris

Tedd

The high-low thing is to accommodate the fact that when multiplying two 32-bit numbers, the result could be more than 32 bits, so the result is stored as 64 bits just in case.
If you know the result of your multiplication is going to fit into 32 bits, then you can ignore the 'high' 32 bits (edx) and just use eax as the result - but still be aware that edx will still be changed, so if you were using it then it will be zeroed after the multiplication.
Division takes a 64-bit number so that you can do a mul and then div without needing to mess around doing the upper and lower parts separately.



{843102945*315395795 = 265911123605116275}

00110010010000001011101011100001 = 32 bits (eax)
(multiplied-by)
00010010110011001000111011010011 = 32 bits (ecx)
(equals..)
00000011101100001011010011000010 00010000010011101101010101110011 = 64 bits (2 sets of 32 bits; edx:eax)

mov eax,843102945    ;00110010010000001011101011100001
mov ecx,315395795    ;00010010110011001000111011010011
mul ecx
;result in edx:eax

;edx => 61912258    ;00000011101100001011010011000010
;eax => 273601907   ;00010000010011101101010101110011
;(61912258*2^32 + 273601907 = 265911123605116275)


..and for your example..

{4 * 5 = 20}
mov eax,4
mov ecx,5
mul ecx
;edx => 0    ;since the result fits into (the lower) 32 bits
;eax => 20
No snowflake in an avalanche feels responsible.

sportskid300

Ohh thanks for the clarifications!
So as long as my strings aren't more than 16bits each, I sould have a resiult in eax only...
Does div work the same way, and does it store the remainder as a whole number?
If I did
mov eax, 22
mov ecx, 5
div ecx

Would it store 4 to eax and 2 to ecx?
Sorry for this continuous barrage...
I can't wait to make windows...

zooba

Don't bother reusing topics by changing the initial post, just start a new one.

That way when people search the forum with the same problem they'll find a question and an answer.

Cheers,

Zooba :U

Tedd

Quote from: sportskid300 on November 30, 2007, 11:40:13 PM
Does div work the same way, and does it store the remainder as a whole number?
If I did
mov eax, 22
mov ecx, 5
div ecx

Would it store 4 to eax and 2 to ecx?

22 / 5 = 4, remainder 2
so: eax =>4, and edx => 2
(you divded BY ecx - the result still goes to eax, edx; while ecx would be left unchanged)


--------

If you want to ask a new question - start a new topic (unless it follows on directly).
Modifying the previous one will only lead to confusion.
No snowflake in an avalanche feels responsible.