What is the value of segment registers in 8086?

时光毁灭记忆、已成空白 提交于 2021-01-28 03:09:14

问题


I have just started to read about intel 8086 and have a question concerning its memory.

I read that the address bus is 20-bit wide, which means the address space is 1MB, and this space is divided into segments.

the question is:

  1. the four segment registers, CS, DS, SS and ES, are they read only or I can set their values, and which are their default values?

  2. I saw the following assembly tutorial:

    ORG 100h
    MOV AX, 0B800h ; set AX = B800h (VGA memory).
    MOV DS, AX ; copy value of AX to DS.
    MOV CL, 'A' ; CL = 41h (ASCII code).
    MOV CH, 01011111b ; CL = color attribute.
    MOV BX, 15Eh ; BX = position on screen.
    MOV [BX], CX ; w.[0B800h:015Eh] = CX.
    RET
    

Concerning the first line, does that mean this code will exist in address 0x100 in code segment space or in the whole address space

and the line:

MOV [BX], CX

Does that mean every time I reference an address in the MOV instruction, the address should be estimated from the start address of the data segment? (as he wrote that the destination is the value + the value in the data segment reg)


回答1:


First, I feel compelled to point out that you appear to be talking here about 8086 "real mode" addressing, which is a very old way of doing things which almost nothing uses anymore. Pretty much all modern operating systems operate in "protected mode", which supports many enhancements (such as flat 32- and 64-bit memory space addressing, virtual memory, etc.) which changes how all of this works substantially.

As far as I know, most operating systems nowadays don't even have any way to run code such as this (in real mode) anymore, so if you're interested in learning assembly for the purposes of programming modern PCs, you might want to find some more recent sources to learn from.

That having been said, assuming you do have some reason to want to do this (such as working with certain embedded processors), or are just curious for historical purposes:

  1. Yes, the 8086 real-mode segment registers can be modified. The instructions and options for doing this are a bit more limited than modifying the more general-purpose registers (for example, there's no instruction to just load a value directly into a segment register, which is why in the code you quoted, the value is first loaded into AX, and then AX is loaded into DS), and can also vary depending on which segment register you're working with.

    In general, you would never want to modify CS (the "code segment") register directly, as that would result in immediately changing what code the processor is running (probably in a way you really don't want). The usual way to modify CS is with a "long jump" or "long call" instruction, which will update both CS and IP (the instruction pointer) at the same time. Likewise, SS (the "stack segment") is usually set at the beginning of program execution and never changed (but it technically could be if you had some really compelling reason to do so).

    DS and ES are general-purpose data segment registers and it was fairly common for programs to change these however they wanted to best access the memory they wanted to work with (as your example code above demonstrates).

    As for the initial values for these registers, those were typically determined by the operating system prior to calling the program's code. Traditionally, in MS-DOS, there were two ways to write programs, as .COM files or as .EXE files. (The ORG 100h line in the code above suggests that it was intended to be run as a COM program.) In the COM case, MS-DOS would initially set all of the segment registers to be the same as CS (that is, they'd all point to wherever DOS had decided to load the program in memory) before invoking the program. The EXE file format was somewhat more sophisticated, and allowed specifying a separate "data segment", in which case the OS would set DS and ES to point to that segment before starting the program instead. In EXE programs, DOS would also typically set up a separate stack segment (SS) for them as well.

  2. The ORG 100h line tells the assembler "assume that the following code will be loaded at address 100h". In real-mode code, addresses such as this are always relative to CS (so the program could actually be loaded many places in memory, as long as CS is set to the correct value to make the code be at 100h relative to CS).

  3. Most addresses for data operations (such as MOV) will be calculated relative to DS by default (for some instructions, you can change that by explicitly specifying a different segment to use, but whether and how you can do that depends on the opcode and the way you're using it). There are, however, a few instructions which are designed to use other segments by default. In summary, it's really best to read the docs for each opcode you want to know about to determine how it uses which segment registers.




回答2:


Get an intel 8088/86 manual. this is all explained in there.

yes you can change them, you would have to be able to change them for them to be useful. The obvious segments are used by default (code for code, data for data), but there are places where you can specify other segments on a data instruction.

The org 0x100 means this code (or data that follows an org directive) starts at address 0x100 within the segment.



来源:https://stackoverflow.com/questions/18837627/what-is-the-value-of-segment-registers-in-8086

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!