-1

I'm writing some x86 assembly language and I am running into a problem. Ultimately, the program asks the user a question and they must answer with 'a' or 'b'. If they pick 'a', the program should jump to say loop two, but if they pick 'b', it should jump to say loop three. My problem is that regardless of what they pick, the program will print both loops two and three.

one:
mov eax, choice1
call print_string
call read_char
cmp al, 'a'
jl three
jmp two
two:
mov eax, choice2
call print_string
call read_char
cmp al, 'a'
jl four
jmp five
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    These things are called "labels" not "loops". A loop is a program construct where a program's control flow repeats a section of the code. A label is an identifier that corresponds to a particular position in a program. Anyway, your example does not contain any spot where the label `three` is defined. Also, `jmp two` followed immediately by the label `two:` is not needed, you can omit that jump and just let the control flow fall through. Also, your label names could be more informative instead of just counting. – ecm Apr 29 '22 at 17:33
  • `jmp two` directly before `two:` is superfluous. Before start of loop `three` (not shown?), i.e. at the end of loop `two` you have to jump somewhere. In comparison to `call`, there is no `ret` or stored return address, you have to decide, where to continue the control for afterwards. Otherwise one control flow just continues with the next one in the program - the programm runs away. – Sebastian Apr 29 '22 at 17:37

1 Answers1

4

The approach I recommend for understanding control flow and how to implement structured statement in assembly is to use the if-goto-label construct that some languages, like C, have.  This approach is fairly universal across assembly languages, and it goes like this:

We have labels, which do not execute, but can be targets of branches.  We also have unconditional branches, in C, the goto label; statement.  We also have conditional branches, which in C are composed of an if and a goto as follows: if ( ... ) goto label;

An if-then-else statement has a pattern in high level language:

if ( <condition> ) {
    <then-part>
}
else {
    <else-part>
}

This same pattern using if-goto-label goes like this:

    if ( ! <condition> ) goto else1;
    <then-part>
    goto endIf1;
else1:
    <else-part>
 endIf1:

The condition needs to be negated or reversed, since in assembly language we tell the processor when to skip the then-part and execute the else-part whereas with an if-then-else the condition is for when to fire the then-part.

In assembly you'll want control structures just like the if-goto-label form I'm showing above.  Remember that labels don't execute or change the behavior of the processor (it actually doesn't even see labels, they are removed by the assembler).

For a nested if statement, we simply follow the pattern translation.  Each individual if-statement needs its own labels, which is why I number them: if1/then1/else1/endif1, if2/then2/else2/endif2...

In assembly language the unconditinoal branch (C's goto label;) is just jmp, and conditional branches are compare followed by conditional branch like jle (jump if signed less-than-or-equal or je (jump if equal).

ecm
  • 2,583
  • 4
  • 21
  • 29
Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • 1
    We already have a canonical Q&A for the bug of letting execution fall through from the `if` block into the `else` block. [Code executes condition wrong?](https://stackoverflow.com/q/32872539). You might want to repost your answer there where future readers are more likely to see it (e.g. following links from any of various previous duplicates, or from https://stackoverflow.com/tags/x86/info) – Peter Cordes Apr 30 '22 at 07:28