2

I am trying to make a custom cursor for my 32-bit OS and would like to know how to offset a memory address (0xb800 for text) by a variable (0xb8000+XVAR). I tried the following but the text just diapered off my screen:

mov al, ' '
mov ah, 0xff
mov edx, 0xb8000+160*3
add edx, CURSORX
mov word [edx], ax

For anyone that needs to know, this is what it looks like without trying to offset: enter image description here And this is what it looks like when I try to offset: enter image description here Best regards, Markian.

Markian
  • 322
  • 1
  • 12
  • 3
    You want `add edx, [CURSORX]` apparently. Then again, this simplifies to `mov edx, [CURSORX]; mov word [edx+0xb8000+160*3], 0xff20` – Jester Jun 24 '22 at 21:37
  • @Jester this did not work, I still got the same result as in picture 2. By the way I define cursorx with the following: `CURSORX: db 0` – Markian Jun 25 '22 at 00:52
  • 1
    It is reading a dword to perform the add, but the variable is defined as a byte. Also each screen element is two bytes, so you need to multiply by 2. To fix both of these, use `movzx edx, byte [cursorx]; add edx, edx; add edx, 0xb8000 + 160*3`. – prl Jun 25 '22 at 01:11
  • Alternatively, `movzx ecx, byte [cursorx]; mov [edx+ecx*2], ax` – prl Jun 25 '22 at 01:14
  • @prl This did not work, I got the same resualt as in picture 2. – Markian Jun 25 '22 at 17:44

1 Answers1

2
mov al, ' '
mov ah, 0xff
mov edx, 0xb8000+160*3
add edx, CURSORX
mov word [edx], ax

The add edx, CURSORX instruction is adding the offset address of the CURSORX variable! To add the value of your variable proper, you must use the square brackets in NASM.

If the mov word [edx], ax instruction works fine (you say without the add it does), it is because the DS segment register is 0. Because your code snippet solely depends on the DS segment register (which is 0), make sure that the offset that NASM gives to the CURSORX variable is also relative to that same zero.

If this is bootloader code and you used an [ORG 0x7C00] directive, all would have been fine (segment-wise).
But if you have used [ORG 0], then make ES=0x07C0 and use a segment override on add edx, [es:CURSORX].


In comments you mention that CURSORX is a byte. You need to extend the byte before using it in the dword-sized addition.

movzx edx, byte [es:cursorx]
mov   word [0xB8000 + 160 * 3 + edx], 0xFF20

And if your 'cursor offset' is expressed in characters, then don't forget to double it before using, because of how the text video memory is organized (character byte, attribute byte)

movzx edx, byte [es:cursorx]
mov   word [0xB8000 + 160 * 3 + edx * 2], 0xFF20
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Hello, this worked for addition but when I tried to multiply it did not work: `mov word [0xB8000 + 160 * edx], 0xFF20` – Markian Jul 10 '22 at 16:56
  • @Markian The 'multiplication' in this scaled addressing operation is not a general purpose multiplication! You can only multiply the index register by 1, 2, 4, or 8. Nothing else. – Sep Roland Jul 10 '22 at 17:01
  • Thank you, it fixed my problem. Also, do you have any idea why it breaks if I do `inc byte [cursorx]`? – Markian Jul 10 '22 at 17:04
  • @Markian Perhaps for the same reason as the one I gave in my answer. Is `DS` suitably setup to point at the *cursorx* variable? Else use the suggested `inc byte [es:cursorx]`. – Sep Roland Jul 10 '22 at 17:09
  • I did use `inc byte [es:cursorx]` but the position of the text became random, sometimes offsetting by 2 others by 20. – Markian Jul 10 '22 at 20:40
  • @Markian It's next to impossible for me (and others) to solve such problems without seeing more of your program. Consider posting a new question that contains the full bootloader (stage 1) and a minimal version of the stage 2 code able to reproduce the error(s). – Sep Roland Jul 10 '22 at 20:58
  • Thank you for your help, However for some reason I am question banned and can not post new questions. – Markian Jul 10 '22 at 21:15