0

I'm trying to get into assembler and I'm reading through a document that gives a short introduction. There is a task to convert the following code to pure assembler code:

mov bx, 30
if (bx <= 4) {
    mov al , ’A’
} else if (bx < 40) {
    mov al, ’B’
} else {
    mov al, ’C’
}
mov ah, 0x0e
int 0x10 ; print the character in al
jmp $
; Padding and magic number.
times 510-($-$$) db 0
dw 0xaa55

I created this assembler code:

mov bx, 30

cmp bx, 4
jle if_branch
cmp bx, 40
jl elif_branch
mov al, 'C'

if_branch:
    mov al, 'A'
elif_branch:
    mov al, 'B'

mov ah, 0x0e
int 0x10

jmp $

times 510-($-$$) db 0
dw 0xaa55

However no matter what I put into bx in line 1 the output will always be 'B'. What am I missing there?

My setup: I'm writing the assembler code in codeblocks and use nasm to create a bin file. Then I execute that bin file using qemu.

SOLUTION thanks to ecm and barny in the comments: The problem was that after the mov al, 'A' in the if_branch label the execution would just continue and execute mov al, 'B'. Defining an empty label in the end and jumping to it solved the problem. Together with some additional improvements this is the final code:

mov bx, 40

mov al, 'A'
cmp bx, 4
jle the_end
mov al, 'B'
cmp bx, 40
jl the_end
mov al, 'C'
the_end:

mov ah, 0x0e
int 0x10

jmp $

times 510-($-$$) db 0
dw 0xaa55
Spray'n'Pray
  • 190
  • 1
  • 15
  • 4
    Hint: what is the next instruction executed after `mov al, 'A'`? – DisappointedByUnaccountableMod Aug 26 '20 at 13:32
  • 1
    Ah yes I see the problem. I solved it by defining an empty label "the_end" before mov ah, 0x0e and jumping there. Is that a valid solution or considered bad practice? – Spray'n'Pray Aug 26 '20 at 13:45
  • 2
    That is a correct solution. However, it is more efficient for code size to do `mov al, 'A'` \ `cmp bx, 4` \ `jle the_end` \ (whatever to do if first condition not true). By pre-initialising the result variable with the first condition's value you can save on the unconditional jump. (Though if the value was read from memory then the read would always occur of course. Need to consider this if the read can fault.) – ecm Aug 26 '20 at 13:52
  • 1
    further hint: is there anywhere else an unconditional jump is needed? – DisappointedByUnaccountableMod Aug 26 '20 at 13:53
  • Thanks so much for you comments @ecm and @barny! I have the following now: mov bx, 4 \ mov al, 'A' \ cmp bx, 4 \ jle the_end \ cmp bx, 40 \ jl elif_branch: \ mov al, 'C' \ jmp the_end \ elif_branch: \ mov al, 'B' \ jmp the_end \ Is that somewhat what you meant? – Spray'n'Pray Aug 26 '20 at 14:06
  • 1
    Yes, but you can do `jle the_end` \ `mov al, 'B'` \ `cmp bx, 40` \ `jl the_end` \ `mov al, 'C'` \ `the_end:` -- that is the trick I listed again for the second and third condition. Also, in your message the last `jmp the_end` is not needed because directly after that jump follows the label `the_end` so for that one you can just "fall through". – ecm Aug 26 '20 at 14:19
  • 1
    @Spray'n'Pray looks better - you can/should edit it into your question as 'updated code' as ecm points out there is also some optimisation possible - it might be that you want to keep the code flowing like the source you show in which case optimisation may not be relevant – DisappointedByUnaccountableMod Aug 26 '20 at 14:21
  • 3
    Not sure what an “empty label” is supposed to be. Note that labels are just that: a label for some piece of code. They don't contain or store anything and cannot be inhabited or empty. – fuz Aug 26 '20 at 14:39
  • @fuz I updated the question with code that I have now thanks to barny and ecm, could you show me a way how to do it without an empty label? – Spray'n'Pray Aug 26 '20 at 14:44
  • 1
    @Spray'n'Pray I can't because I don't know what an “empty label” is supposed to be. – fuz Aug 26 '20 at 14:47
  • Your case is very special, and can be done without using conditional jumps: `mov bx, 30` `mov al, 'C'` `cmp bx, 40` `sbb al, 0` `cmp bx, 5` `sbb al, 0`. `cmp` sets `CF` if the first operand is smaller (unsigned comparison). `sbb al, 0` subtracts 0 and `CF` from `AL`. – W. Chang Aug 27 '20 at 14:55

0 Answers0