2

I am learning x86 assembly language, and I understand the purpose and usage of segments. Segments hold vital data, and can also be used to store extra data (ie. Memory Segmentation Model). Here is my question though. If segments can be used to store extra data, how can I make sure that my storing data in them won't overwrite any existing data?

For example, the CS register points to the Code Segment. The Code Segment contains the program's code. If I used the CS register with an offset to store some data, how would I know where to put my data so as not to overwrite the code that it is storing?

Please let me know. I using Intel syntax assembly and assembling with NASM.

Thanks

starblue
  • 55,348
  • 14
  • 97
  • 151
QAH
  • 4,200
  • 13
  • 44
  • 52

4 Answers4

3

Segments never store any data. The segment registers are just "base" address pointers which are used to create 20-bit pointers using only 16-bit registers. For example:

MOV DS, 0001
MOV DI, 0013
MOV AL, DS:[DI]  ' this reads from address x00023 in memory

MOV DS, 0002
MOV DI, 0003
MOV AL, DS:[DI]  ' this too reads from address x00023 in memory

MOV DS, 0000
MOV DI, 0023
MOV AL, DS:[DI]  ' this too reads from address x00023 in memory

As for your question how to make sure that you don't overwrite code with data: it's entirely up to you make sure that you know exactly where in memory you store your code and data!

Dan Byström
  • 9,067
  • 5
  • 38
  • 68
  • Ok thanks for that clarification. But how can I know where in memory my code and data lies? – QAH Oct 23 '09 at 08:59
  • 2
    I'm sorry, but I realise as I type this that a full explanation will be way way toooo loooong... :-( All I can say: keep studying. You'll probaby have a great experience digging into this concept! – Dan Byström Oct 23 '09 at 09:12
  • 2
    By the way, there is no instruction for moving an immediate value to a segment register. Instead of MOV DS, 1 you'll need to do go through another register, like MOV AX, 1 MOV DS, AX or the stack, like PUSH 1 POP DS – I. J. Kennedy Oct 27 '09 at 19:43
0

It's assembly, so you are responsible for everything. To keep your code and data separate is just as easy as keeping two numbers separate. Just use each memory location at most once.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

In addition to what's been said already, I'd like to add that you wouldn't normally want to store any "data" in the code segment. That's why you have a Data Segment (base pointed to by DS) or even an "extra" data segment (-> ES). Obvisouly, since your basic assumption must be that whatever is in the code segment, will be executed, it would be very unwise to write random data values there.

If you must store data in the code segment, make sure it will never be executed, like below:


..some code here..
jmp AfterDataDeclaration
  db 12  ; declare some data here
AfterDataDeclaration:
..some more code here..

[edit:] If you want to access any specific data, you will always need a reference point, which you will usually most conveniently declare by a label. The assembler will let you access this symbolically, without you having to know its actual address.

The one case where you might want to write something to the code segment is if you want to patch machine code there (i.e., self-modifying code).

PhiS
  • 4,540
  • 25
  • 35
  • So when you assemble software, is ES filled with anything or does that stay empty for our messing around with? – QAH Oct 24 '09 at 03:36
  • @QAH: It's your own responsibility to set up the segment registers to point to anything useful. I don't know about NASM and it's a long time since I did 16-bit MASM assembly. IIRC, MASM had the "ASSUME" directive which told the assembler to set up the segment registers for you. – PhiS Oct 24 '09 at 11:07
0

As they already mentioned, segment register hold only a 16 bit pointer. This pointer is internally multiplied by 16 so that CPU can address 20-bit big address memory space.

1) If you have enough memory than you can choose 64Kb of RAM for stack, 64Kb for data memory and rest for code memory. Let say that SS (stack segment register) is 0x0400 and DS (data segment register) is 0x0800 and CS (code segment register) is 0x1B00. In this case your code can't override any other memory segment. If you need another 64K of data memory than you can simple extend it with use of ES segment and ES prefix.

2) If you don't have enough memory space (compact program) than you must predict the memory boundaries.

3) If your program use external calls with memory pointers than you must check boundaries. For this purpose in x86 mnemonic exist BOUND instruction.

GJ.
  • 10,810
  • 2
  • 45
  • 62