x / 2 + 100 * (a + b) - 3 / (c + d) + e * e en conjunto

Oct 21 2020

escribir un algoritmo para: x / 2 + 100 * (a + b) - 3 / (c + d) + e * e sabiendo que: a, c - palabra, b, d - byte, e - palabra doble, 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

¿Lo hice innecesariamente complicado?

Respuestas

6 SepRoland Oct 22 2020 at 03:52

escribe un algoritmo para: x / 2 + 100 * (a + b) - 3 / (c + d) + e * e

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

Debido a que su número más grande es 64 bits ( x es una palabra q), ¡su resultado final también tendrá que ser 64 bits!

Su primera operación fue dividir la palabra q en x por 2. Parece esperar que este resultado quepa en una sola palabra d porque ha movido el cociente en el EBXregistro. No se puede hacer esta suposición y, peor aún, la división podría producir fácilmente una excepción de división si el cociente no encaja en 32 bits.
Para la solución, debe tener en cuenta que dividir por 2 en realidad es simplemente un desplazamiento hacia la derecha.

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

Esto significa que también tendrá que escalar los otros cálculos para agregarlos al EBP:EBXuso:

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

Como la suma es asociativa, puede comenzar calculando la parte e * e . No reorganizó la expresión y al final tuvo que moverse un poco más por los registros. No es gran cosa, pero es más agradable a mi manera:

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

Luego viene 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

Te dejo 3 / (c + d) ...

... y finalmente el final será:

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

¿Lo hice innecesariamente complicado?

  • Fue un poco difícil leer su programa porque no insertó algunas líneas en blanco entre las diferentes operaciones.

  • No es necesario escribir una etiqueta de tamaño (byte, palabra, dword) si el registro involucrado ya implica el tamaño. En mov dword [result + 0], eaxla etiqueta dword es redundante.

  • Es mejor que los comentarios del programa estén alineados uno encima del otro.

  • Vuelva a leer con atención para evitar errores tipográficos como en:

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

    Debería ser ECX:EBX.

  • Para calcular un cuadrado: una vez que haya cargado el número en el registro, puede multiplicar por ese mismo registro y no recurrir a la memoria por segunda vez como lo hizo:

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