0

Im trying to make fizzbuzz in assembly x86 64 but i dont know how to make a loop that has conditional statements

I thought i would check for a condition and then jump to that procedure and then ret back. The problem is that if I return the label I will get a segfault for some reason.

The problem in the current code is that the fizzCondition will always execute

 mov ax, 6 mov bl, 3 div bl cmp ah, 0 je fizzCondition ;check buzz condition etc.. fizzCondition: mov eax, SYSWRITE mov edi, 1 mov esi, fizz mov edx, 5 syscall exit 

if I do it like this I will get a segfault:

 mov ax, 6 mov bl, 3 div bl cmp ah, 0 je fizzCondition exit fizzCondition: mov eax, SYSWRITE mov edi, 1 mov esi, fizz mov edx, 5 syscall ret 
2
  • As a rule of thumb, you can only ret from something you call. Either just jump back instead of ret or put a call in the conditional, for example by reversing the condition: jne notFizzCondition; call fizzCondition; notFizzCondition: ... Commented Jun 2, 2022 at 11:34
  • See also What are callee and caller saved registers? re: your callee stepping on registers you use in the loop. See also FizzBuzz in assembly - segmentation fault re: using down-counters instead of actually doing a slow div every iteration. My answer there has a semi-optimized FizzBuzz, storing strings into a buffer for fewer write syscalls. (The major factor in performance, much bigger than avoiding div.) Commented Jun 2, 2022 at 18:46

1 Answer 1

1

You need to use a call instruction to call a function. The call instruction records the return address on the stack so the function you called can return. If you just jump to the function, it'll return to whatever is on the stack, causing a crash. So to fix your code, change it to read:

 mov ax, 6 mov bl, 3 div bl cmp ah, 0 jne around call fizzCondition ; this executes only when AH==0 around: exit fizzCondition: mov eax, SYSWRITE mov edi, 1 mov esi, fizz mov edx, 5 syscall ret 

Another thing you'll have to pay attention to is that there is only one set of registers. fizzCondition overwrites the registers eax, edi, esi, and edx so you'll need to save their contents somewhere (e.g. on the stack) if you want them to be preserved.

Sign up to request clarification or add additional context in comments.

2 Comments

so then in around i should do the buzz condition check?
@user259137 The label around is just to have the condition inverted: we do the call if the condition is not “not-equal.” So yes, do the condition check right after. Note that labels just mark spots in the code. They are not containers or anything. There is no “in a label.”

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.