1

I'm trying to implement the following pseudocode in assembly: enter image description here

My solution tries to implement the while loop using a LOOP instruction, but this gives me an infinite loop. (I know this is b/c of the garbage values in the ECX, but I don't understand how to overcom this problem and correctly implement the WHILE loop). Here's my code:

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
A WORD 9
B WORD 8
X WORD 15
sum WORD 0

.code
main PROC
L1:
    cmp X, 3     
    jne ELSEE   ;jump to ELSEE if X!=3 (short circuits the AND condition)
    mov ax, A+3
    cmp X, ax
    jle TRUE  ;jump to TRUE if X<=A+3
    mov bx, B-3
    cmp X, bx
    jl TRUE ;jump to TRUE if X<B-3
    cmp X,0
    jge WHYLE

    TRUE:
        sub X,2
        inc sum
    ELSEE:
        dec X
WHYLE:
    loop L1

    invoke ExitProcess, 0
main ENDP
END main
trufflewaffle
  • 179
  • 10
  • 1
    Since you can't easily calculate the number of iterations ahead of time, don't use `loop`. use `test eax,eax` / `jge` as the loop branch to implement the `while(x>=0)` logic. (With X in EAX) – Peter Cordes Apr 02 '21 at 20:34
  • Also, `mov bx, B-3` is a word load from the address `[B-3]`, that's also not what your pseudocode is doing. – Peter Cordes Apr 02 '21 at 20:35
  • @PeterCordes could you please elaborate on your first comment about using the `test` instruction – trufflewaffle Apr 02 '21 at 20:39
  • 2
    Look at compiler output for a C version of the pseudocode; e.g. from https://godbolt.org/ with `gcc -Og -m32` or MSVC. ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)). For test/jge specifically, [Test whether a register is zero with CMP reg,0 vs OR reg,reg?](https://stackoverflow.com/a/33724806). Using cmp/`jcc` for a loop isn't fundamentally different from using it for an `if`, it's just a matter of jumping backwards to re-run the loop body. – Peter Cordes Apr 02 '21 at 20:41

1 Answers1

1

If the comparison yields greater or equal, jump to the start, otherwise continue out of the loop, e.g. to the exit call. This is effectively a do{}while() loop, which is most natural in asm. Since you can't easily calculate ahead of time how many iterations the loop needs to run, you can't use the loop instruction as the loop condition.

There are other bugs inside you loop body, but this is how to loop. You might want to keep X in a register instead of using memory every time you access it.

    cmp X,0
    jl SKIP      ; skip the loop entirely if the condition is false to start with

L1:              ; do {

   ;;; loop body goes here
    
    cmp X,0
    jge L1       ; }while(X >= 0);
SKIP:

   ;; after the loop
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Mirronelli
  • 740
  • 5
  • 14
  • 2
    Yup, that's the standard way to make a `while()` loop. There are in fact several other bugs (like the if/else logic, and doing memory offsets instead of load / add), so maybe it would be better to cut out all the other code and just say "loop body goes here" without showing the still-wrong code. – Peter Cordes Apr 02 '21 at 20:46