More Assembly :(

Sorry for all the assembly! I already hate coding in it.

When I go to divide, it gives me some out of this world answers. This works:

1
2
3
4
mov ax, 11
mov bl, 37
div bl
mov [bAns16], ah



And will give me the correct remainder of 11. But as soon as I switch those numbers to variables, the whole thing breaks:


1
2
3
4
5
6
7
8
mov ax, [bNum1]
mov bl, [bNum4]
div bl
mov [bAns16], ah


;bNum1 = 11
;bNum4 = 37



The answer should be 0 with a remainder of 11. But the answer ends up 104 and with a remainder of 3 somehow.


Moreover, I'm having issues with using imul - makes no sense at all. Same as with div:

1
2
3
4
mov ax, 33
mov bx, -17
imul ax, bx
mov [wAns15], ax


Will give me the correct answer, but won't as soon as I put variables in there:

1
2
3
4
5
6
7
mov ax, [bNum5]
mov bx, [bNum6]
imul ax, bx
mov [wAns15], ax

;bNum5 = 33
;bNum6 = -17



So it should equal -561, but gives me -32049 instead consistently.


What am I doing wrong? Assembly hurts me internally.
Last edited on
A personal aside......just commentary, no real advice or help.

Assembly coding is one of the main reasons why I began to learn C++ on my own.

C is bad enough for making simple "oops!" errors, but assembly is like using an elephant gun to swat a fly.
Figured that out myself. It's pretty easy to understand, but very easy to mess up any little thing
Hello zapshe,

In the first example, I can’t get the correct answer. The reason is 37 is a 16-bit number (bx) and not an 8-bit number (bl), and it should give an error. My error is “operand size conflict” for the first part of your question on Visual Studio 16.4.4 C++ 2019.

1
2
3
4
5
6
7
INT16 bAns16 = 0;
__asm {
       mov ax, 11
       mov bl, 37
       div bl
       mov [bAns16], ah //error line ‘operand size conflict’
       }


The following code has no errors on my machine and has the correct quotient of 0, and remainder of 11. All numbers are 16-bit.

1
2
3
4
5
6
7
8
9
INT16 bAns16;
INT16 bNum1 = 11;
INT16 bNum4 = 37;
__asm {
       mov ax, [bNum1]
       mov bx, [bNum4]
       div bx
       mov [bAns16], ax
       }


Does this assembly code for the first part of your question work on the computer?
Hi zapshe,

In the second part of the multiplication question, I am guessing that you are attempting to use a 15-bit answer by the use of the variable name wAns15. This needs to be a 16-bit value for the negative value to properly be counted, as the 16th-left-bit is the indicator for a positive or negative sign. The following code on my computer gives me -561 on Visual Studio 16.4.4 C++ 2019.

1
2
3
4
5
6
7
INT16 bAns16 = 0;
__asm {
       mov ax, 33
       mov bx, -17
       imul ax, bx
       mov [wAns16], ax
       }



The following code has no errors on my machine and has the correct quotient of -561 and requires 16-bit variables.

1
2
3
4
5
6
7
8
9
INT16 wAns16;
INT16 bNum5 = 33;
INT16 bNum6 = -17;
__asm {
       mov ax, [bNum5]
       mov bx, [bNum6]
       imul ax, bx
       mov [wAns16], ax
       }


Do your computer show -561 with this code?

Edit: Changed wording to include indicator, as there is more to it for negative values.
Last edited on
You declared the variables as INT16, mine are declared as a single byte (as given to us). Assembly sucks. I got a few answers on stackoverflow that helped me solve why imul wasn't working. It was because it was putting the 1byte value in a 2byte container, so it was going into the variable after it to get the data.

I was able to get div to work using the same logic, with either cbw or mov ah, 0:

1
2
3
4
5
6
7
8
9
10
mov al, byte [bNum1]
;cbw
mov ah, 0
div byte [bNum4]
mov [bAns16], ah

mov ax, [bNum2]
cbw
div byte [bNum3]
mov [bAns17], ah



I'm still working on getting this to work though:

1
2
3
4
5
6
7
8
9
10
11
12
;	bAns18 = wAns13 / bNum2
;	bRem18 = wAns13 % bNum2

mov ax, word [wAns13]
cwd
div byte [bNum2]
mov [wAns18], al
mov [wRem18], ah


;wAns13 is 407
;bNum2 is 15


I've tried everything it seems. I wish assembly could go die in a ditch.

Thanks for the response!
Last edited on
That's gratitude for you. In short repliers, you wasted your time.
For the sake of completeness and for those who will look at the cplusplus forums in the future for answers, here is one possible working answer to zapshe's last question:

1
2
3
4
5
6
7
8
9
10
11
12
INT16 wAns13 = 407;
INT16 bNum2 = 15;
INT16 wAns18;
INT16 wRem18;
__asm {
            mov ax, [wAns13]
            div [bNum2]
            mov[wAns18], ax
            mov[wRem18], dx
            }
;wAns18 = 27
;wRem18 = 2


Both wAns18 and wRem18 are INT16 variables, and a 16-bit ax quotient is used with a 16-bit remainder dx.

Edit: Removed cwd as this command is not required.
Last edited on
Topic archived. No new replies allowed.