0

I'm trying to print the symbol with teletype. Here's the piece of code:

mov al, [smb]
int 0x10

smb: db "X"

But it turns out that this shows any arbitrary symbol from memory rather than from this location. Seems like [] returns the relative address of the symbol. It may be expected, but the question is: how can I find the absolute address? I'm using QEMU-i386, assembling with standard NASM.

P.S. After reviewing other questions related to NASM: please, don't tell me to go check docs of NASM as a lot more people ask here a lot of simple questions about C#, but they're not sent to Richter.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
JohnIdlewood
  • 356
  • 3
  • 12
  • You should provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). – ecm Dec 12 '19 at 21:58
  • 2
    `mov al, [smb]` move the byte (`X` in this case) at `smb` to _AL_. Which is what you probably want to have done. I assume you have moved `0x0e` into _AH_ to make the TTY output call via BIOS service int 10h. You probably want to place an infinite loop or something between the int 0x10 and the data right below so you don't fall through and start executing code as data. But if I had to guess, your problem may be that DS segment register points to the wrong segment. If you showed all your code it would help. I gather you are probably doing this in some kind of bootloader or first stage? – Michael Petch Dec 12 '19 at 22:13
  • 3
    The other possibility is you didn't set the ORG statement according to what your code expects. For example in a **bootloader** I usually use an `ORG 0x7c00` at the top of the NASM file and then at the top of my bootloader code I set DS to 0 with something like `xor ax,ax` `mov ds, ax` – Michael Petch Dec 12 '19 at 22:19
  • Thank you! Calling **ORG 0x7c00** worked even without setting DS to 0x00. Yes, I was building a simple boot sector for a hobby project – JohnIdlewood Dec 14 '19 at 08:38

2 Answers2

3

For 64-bit code; the default is absolute addressing, and to get RIP relative addressing you'd use something like mov al, [rel smb]. However; the default can be changed with a DEFAULT REL directive; and in that case if you want absolute addressing you'd use something like mov al, [abs smb].

For 16-bit and 32-bit code; absolute addressing is the only option (ignoring the hopefully unnecessary confusion of "absolute address encoded as relative displacement" which occurs for some jumps and calls, which can't matter for mov al, [smb]).

For both cases (16-bit and 32-bit code, and 64-bit code); "absolute addressing" is actually an absolute offset from the segment base. For example, mov al, [smb] will implicitly use the DS segment, so if the base address of the DS segment is not zero (which is only possible for 32-bit and 16-bit code - for 64-bit code only FS and GS can have a segment base) the actual absolute address will be "segment base + absolute offset". If the segment base is zero this can be ignored ("segment base + absolute offset" = "0 + absolute offset" = "absolute offset").

Of course how the absolute offset is determined depends on which section it is in and where the section begins; which (depending on output file format - flat binary vs. object file) depends on an org directive, or section definitions, or a linker.

Brendan
  • 35,656
  • 2
  • 39
  • 66
0

The instruction you are looking for is Load Effective Address: What's the purpose of the LEA instruction?

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101