0

I have made a simple program inside assembly which compares two numbers. For some reason, when the numbers are equal, the program works as expected. However, when the numbers are not equal, there is a segmentation fault.

Here is my code:

  1 section .data
  2         entermsg db 'Enter a Number: '
  3         lenenter equ $-entermsg
  4 
  5         equalmsg db 'The two numbers are equal'
  6         lenequal equ $-equalmsg
  7 
  8         nemsg db 'The two numbers ARE NOT equal    '
  9         lennemsg equ $-nemsg
 10 
 11 section .text
 12         global _start
 13 
 14 _start:
 15         mov ax, 1
 16         mov bx, 4 ; When values inside ax and bx are equal, the program works
 17 
 18         cmp ax,bx
 19         je equal
 20 
 21         cmp ax,bx
 22         jne unequal
 23 
 24         mov eax, 1
 25         int 0x80
 26 
 27 equal:
 28         mov eax, 4
 29         mov ebx, 1
 30         mov ecx, equalmsg
 31         mov edx, lenequal
 32         int 0x80
 33 
 34         mov eax, 1
 35         int 0x80
 36 
 37 unequal:
 38         mov eax, 4
 39         mov ebx, 1
 40         mov ecx, nemsg
 41         mov edx, lennemsg
 42         int 0x08
 43 
 44         mov eax, 1
 45         int 0x80

I am using NASM and linker on Ubuntu 16.04LTS

Any help is appreciated! Thanks

Logan Darby
  • 145
  • 15
  • Your messages are missing the null terminator. – Havenard Sep 23 '16 at 00:12
  • Possible duplicate of [db usage in nasm, try to store and print string](http://stackoverflow.com/questions/25212410/db-usage-in-nasm-try-to-store-and-print-string) – Havenard Sep 23 '16 at 00:14
  • @Havenard No, that's not the problem. If it was, the program wouldn't work when the numbers are equal. – Logan Darby Sep 23 '16 at 00:19
  • 1
    @Havenard : They don't need `nul` termination since the sys_write call requires a length parameter. The length being passed is the exact number of characters needed. It is not undefined behavior to print an exact number of characters without a `nul` with sys_write syscall. It is very defined. Call to `printf` would be a different story. – Michael Petch Sep 23 '16 at 00:23
  • 1
    @LoganDarby You can't make that conclusion when it comes to undefined behavior, so I suggest you fix your code. In any case, have you noticed you are calling a `int 0x08` when its supposed to be a `int 0x80`? – Havenard Sep 23 '16 at 00:23
  • The problem appears to be a typo. You have `int 0x08` should be `int 0x80` – Michael Petch Sep 23 '16 at 00:23
  • @MichaelPetch Thank you, that worked perfectly! – Logan Darby Sep 23 '16 at 00:28
  • after `je equal` the `cmp ax,bx` at line 20 is redundant, you already did that `cmp` ahead of `je`, and `je` instruction does not modify flag register value, so all the flags set from first compare are still there. Notice the flags are just a number stored in `f` register, similar to any other register, except there are few instructions to manipulate it directly. When learning the instructions, learn roughly which instruction does modify flags (ideally even "how", so you don't have to list trough reference guide every time you need it, but at least be aware). And lines 24/25 are not reachable. – Ped7g Sep 23 '16 at 09:27
  • So the whole part at lines 21-25 can be replaced by simple `jmp unequal`. I'm posting this not to learn you how to optimize your code, but to make you aware you have confusing logic above the assembly level. Before writing the code, make sure your higher logic is simple enough without obvious redundancy, it will save you from some typing. – Ped7g Sep 23 '16 at 09:33
  • Thank you @Peg7g, I will be aware of this next time. My code has been fixed, and I've put some more research into flags. – Logan Darby Sep 23 '16 at 13:50

0 Answers0