assemblynasmmemory-addressosdevprotected-mode

Use variable to offset text in 32-bit protected mode


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.


Solution

  • 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