Assembly Question

Hope there's someone here who knows enough to help, haven't been understanding this.

I have two number variables and an answer variable (where I store the answer). I need to multiply the two variables and store it into the answer variable. This code does this, but no idea why:

1
2
3
4
mov al, [bNum2]
mov bl, [bNum3]
mul bl
mov [wAns11], ax


From what I've learned, mul should be saving into ax, which it does - so how does it know to grab bl and al to multiply together?? Whenever I try this:

1
2
3
4
mov ax, [bNum2]
mov al, [bNum3]
mul al
mov [wAns11], ax



It gives me the wrong answer, though it's a consistent one. I also don't understand why this one works:

1
2
3
4
mov ax, [bNum2]
mov ah, [bNum3]
mul ah
mov [wAns11], ax


Why did using al give me the wrong answer but ah give me the right one? What am I missing?


Thanks <3


EDIT:

I was looking at this:

https://stackoverflow.com/questions/40893026/mul-function-in-assembly


The example on the site doesn't work when I use it with my variables:

1
2
3
mov  ax, [bNum2]
mov  cx, [bNum3]
mul  cx


This one gives me a random negative number. I don't get what's happening. Why aren't the different registries interchangeable?
Last edited on
OOOhhhhh, is it because ax is having its information stored in al, so the second example doesn't work because it's multiplying bNum3 by itself - because it overwrites the original value written in ax. And the first example works because what we saved in a1 IS what mul uses when accessing ax.

Alright, I think I get it now. Would have helped if the professor had made it clear that al/ah and ax weren't different memory locations. I assume this applies to eax and rax as well.
https://www.felixcloutier.com/x86/mul
> Performs an unsigned multiplication of the first operand (destination operand)
> and the second operand (source operand) and stores the result in the destination operagtnd
mul a b is equivalent to a *= b

> The destination operand is an implied operand located in register AL, AX or EAX
> (depending on the size of the operand)
mul b is equivalent to al *= b

> The result is stored in register AX (...)
> with the high-order bits of the product contained in register AH
so it's actually mul b === ax = al*b


so
1
2
mov al, [bNum3]
mul al
is equivalent to al*al, same as bNum3*bNum3

1
2
3
mov ax, [bNum2]
mov ah, [bNum3]
mul ah
'ah' is a byte, so that did ax = al*ah
`bNum2' happens to enter in al

1
2
3
mov  ax, [bNum2]
mov  cx, [bNum3]
mul  cx

because cx is a 'word' the result will be in dx:ax
(see table 4-9)


> Would have helped if the professor had made it clear that
> al/ah and ax weren't different memory locations
think of it like a union
al, lower bits of ax
ah, higher bits of ax

ax, lower bits of eax
to be very clear on intel each register is a letter, a,b,c etc. eax is still the A register. You can do work on small things (bytes, and I think 2-byte ints) all in one register if I remember it, and the bigger stuff (32, 64 bit) need a full register each. (I don't think they made instructions to access a 64 bit register as 2 32 bit ints, but I could be wrong). You mostly want to think of them as A register or B register, to keep it straight.
Last edited on
The "e" in "eax" means "extended", BTW.

Thanks for the info guys! This professor just breezes through the material and barely explains along the way.

EDIT:

Thanks again guys, the more I read over these things the more sense it makes. Extremely helpful. Three comments on this post were more helpful than an entire class period with the professor !
Last edited on
Topic archived. No new replies allowed.