You may want to take a look at the ASE 12.5.1 Transact SQL Guide, Chapter 18 - Cursors: Accessing Data Row by Row. It's a bit dry reading but should address your questions. As long as you ignore the newer syntax you could also look at the same T-SQL guide for newer ASE versions to get a better description of how the cursor works.
In a nutshell your cursor is sensitive to changes in the underlying table (eg, when your update causes rows to change their position in the table this can lead to rows either 'disappearing' or 'reappearing' during cursor processing).
What you want to do is make the cursor insensitive to changes in the underlying table. With ASE 12.5.4 this is typically implemented by ensuring the cursor uses a unique index or processes rows from a worktable. (ASE 15.x adds a sensitivity clause to the 'declare/cursor' command.)
If you can't put a unique index on the table you could try a couple other options to see how your cursor performs, eg, add a 'for read only' clause to the 'declare/cursor' command, try defining the table with datarows (as opposed to allpages) locking.