The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: sportskid300 on November 28, 2007, 01:58:15 AM

Title: use of .if statemet, among other questions
Post by: sportskid300 on November 28, 2007, 01:58:15 AM
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]
Title: Re: use of 'dd' and 'db', among other questions
Post by: MichaelW on November 28, 2007, 03:00:14 AM
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 (http://developer.intel.com/products/processor/manuals/index.htm).
Title: Re: use of 'dd' and 'db', among other questions
Post by: Tedd on November 28, 2007, 01:29:16 PM
"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)
Title: Re: use of 'dd' and 'db', among other questions
Post by: sportskid300 on November 30, 2007, 12:34:34 AM
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
Title: Re: use of 'dd' and 'db', among other questions
Post by: ChrisLeslie on November 30, 2007, 02:25:15 AM
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
Title: Re: use of 'dd' and 'db', among other questions
Post by: Tedd on November 30, 2007, 12:52:20 PM
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
Title: Re: use of 'dd' and 'db', among other questions
Post by: sportskid300 on November 30, 2007, 11:40:13 PM
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...
Title: Re: use of .if statemet, among other questions
Post by: zooba on December 01, 2007, 01:16:52 AM
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
Title: Re: use of 'dd' and 'db', among other questions
Post by: Tedd on December 01, 2007, 02:52:31 PM
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.