7
\$\begingroup\$

write an algorithm for: x / 2 + 100 * (a + b) - 3 / (c + d) + e * e knowing that: a, c - word, b, d - byte, e - doubleword, x - qword

    mov eax, dword [x]
    mov edx, dword [x + 4] ; edx:eax = x
    mov ebx, 2
    idiv ebx ; eax = edx:eax / ebx = x / 2
    mov ebx, eax ; save the result in ebx so we can do the other operations
    mov al, [b]
    cbw ; ax = b
    add ax, [a] ; ax = a + b
    mov dx, 100
    imul dx ; dx:ax = ax * dx = 100 * (a + b)
    push dx
    push ax
    pop eax ; 100 * (a + b)
    add ebx, eax ; ebx = x / 2 + 100 * (a + b)
    mov al, [d] ; al = d
    cbw ; ax = d
    add ax, word [c] ; ax = c + d
    mov cx, ax ; cx = c + d
    mov ax, 3
    cwd
    idiv cx ; ax = dx:ax / cx 
    cwd
    push dx
    push ax
    pop eax ; eax = 3 / (c + d)
    sub ebx, eax
    mov eax, ebx
    cdq ; edx:eax = x / 2 + 100 * (a + b) - 3 / (c + d)
    mov ebx, eax
    mov ecx, edx ; ecx:edx = x / 2 + 100 * (a + b) - 3 / (c + d)
    mov eax, [e]
    imul dword [e] ; edx:eax = e * e
    add eax, ebx
    adc edx, ecx
    mov dword [result + 0], eax 
    mov dword [result + 4], edx

did I make it unnecessarily complicated?

\$\endgroup\$
5
  • 2
    \$\begingroup\$ "Is it correct?" That's a question for you to answer before posting here. If it is not doing what it is supposed to, it is offtopic here. So, is it correct? If yes, please remove that sentence as it may seem to imply that you don't know if your code works correctly, giving others a reason to vote to close your post... \$\endgroup\$ – slepic Oct 21 '20 at 4:50
  • 1
    \$\begingroup\$ I'm sorry! it works but I'm new to assembly language and I didn't know if it was legit \$\endgroup\$ – just1frustredstudent Oct 21 '20 at 4:52
  • 1
    \$\begingroup\$ kk, that's fine, I actualy thought it will be the case, but I wanted to prevent any further confusion, thanks \$\endgroup\$ – slepic Oct 21 '20 at 4:53
  • \$\begingroup\$ What is the target platform ? \$\endgroup\$ – Anonymous Oct 21 '20 at 20:46
  • \$\begingroup\$ Note that the entire expression is undefined for c=-d. \$\endgroup\$ – slepic Oct 22 '20 at 3:35
6
\$\begingroup\$

write an algorithm for: x / 2 + 100 * (a + b) - 3 / (c + d) + e * e

a, c - word,
b, d - byte,
e - doubleword,
x - qword

Because your biggest number is 64 bits (x is a qword), your final result will have to be 64 bits too!

Your first operation was to divide the qword in x by 2. You seem to expect that this result will fit in just a single dword because you've moved the quotient in the EBX register. You cannot make this assumption and worse the division could easily produce a divide exception if the quotient doesn't fit in 32 bits.
For the solution you should be aware that dividing by 2 is actually simply a shift to the right.

mov   ebx, [x]
mov   ebp, [x + 4] ; EBP:EBX is x
sar   ebp, 1
rcr   ebx, 1       ; EBP:EBX is x / 2

This means that you'll have to scale up the other calculations too in order to add them to EBP:EBX using:

add   ebx, ...
adc   ebp, ...

Because addition is associative, you can start by calculating the e * e part. You did not rearrange the expression and had to move around some more the registers in the end. Not a big deal, but nicer my way:

mov   eax, [e]
imul  eax
add   ebx, eax
adc   ebp, edx

Then comes 100 * (a + b):

movsx eax, word [a]
movsx edx, byte [b]
add   eax, edx       ; eax = a + b
mov   edx, 100
imul  edx            ; edx:eax = 100 * (a + b)
add   ebx, eax
adc   ebp, edx

I'll leave 3 / (c + d) to you...

... and finally the end will be:

sub   ebx, eax
sbb   ebp, edx
mov   [result + 0], ebx 
mov   [result + 4], ebp

did I make it unnecessarily complicated?

  • It was a bit hard to read your program because you didn't insert some blank lines between the different operations.

  • You don't need to write a size tag (byte, word, dword) if the register involved already implies the size. In mov dword [result + 0], eax the dword tag is redundant.

  • Best have the comments in the program aligned above each other.

  • Reread carefully to avoid typos like in:

      mov ecx, edx ; ecx:edx = x / 2 + 100 * (a + b) - 3 / (c + d)
    

    Should be ECX:EBX.

  • To compute a square: once you've loaded the number in the register, you can multiply by that same register and not turn to the memory a second time like you did:

      mov   eax, [e]
      imul  eax        ; Don't write "imul dword [e]"
    
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.