SP can't be used as a base or index register in the 16-bit addressing modes. Unlike the 32-bit addressing modes the allowed modes are very restricted as to what registers can be used.
You're limited to the following modes (%bx)
, (%bp)
, (%si)
, (%di)
, (%bx,%si)
, (%bx,%di)
, (%bp,%si)
and (%bp,%di)
. These can all have an optional 8-bit or 16-bit displacement. (Strictly speaking (%bp)
must have displacement, but the assembler will use a 0 displacement if you don't provide one) Note that the addressing modes that use BP as a base also default to the stack segment (SS) rather than data segment (DS).
A partial solution in your case would be to use BP as your base instead, copying the value from SP first. Alternatively you could use ESP as your base and so use 32-bit addressing where it's allowed.
However there would be still be fundamental problem with what you're attempting. You're trying to store values at addresses below the stack pointer. These addresses will be overwritten by future pushes and calls, and unpredictably by interrupts. Even you've disabled interrupts and are not using any instructions that use the stack, it would still be a good idea to properly allocate the the space on the stack for the memory you're using.
For example:
movw %sp, %bp
subw $6, %sp
movw $0xd000, -2(%bp)
movw $0, -4(%bp)
movw $1, -6(%bp)