About 16-bit and 32-bit code segments

Source: Internet
Author: User

From: http://hi.baidu.com/phps/blog/item/48a2a83487ab1eb3d1a2d371.html

After debugging a piece of protection mode code, I found that the original code segment switched from 16-bit direct JMP to 32-Bit During the protection mode caused an exception, search for this article on the Internet and transfer it to the archive!

About 16-bit and 32-bit code segments

For ix86 programming, sometimes it is necessary to change from the real mode to the protection mode (for example, to access extended memory in the DOS era, or to write pilot code, of course, if you program in a 32-bit operating system, you won't be able to solve this problem.) It always involves the jump between 16-bit code segments and 32-bit code segments. Therefore, it is necessary to differentiate them.

The main difference between a 16-bit code segment and a 32-bit code segment is that in a 16-bit code segment, the offset of the jump target is represented by 16 bits. In a 32-bit code segment, the offset of the jump target is expressed in 32 bits.

In real mode, the CPU always performs a 16-bit jump, that is, when it parses the jump target, it always reads the 16-bit value in the memory as the jump target. Therefore, the assembler must work with the CPU to generate the code that uses 16 bits to represent the offset.

In the protection mode, the problem is a little more complicated, because how the CPU parses the jump target at this time is related to the attribute of the target code segment. In protection mode, each code segment is represented by a code segment descriptor. A field in the code segment descriptor indicates whether the segment is a 16-bit code segment or a 32-bit code segment. If the jump target is in a 16-bit code segment, the CPU reads a 16-bit value from the memory as the jump offset. If the jump target is in a 32-bit code segment, the CPU reads a 32-bit value from the memory as the redirection offset. In the protection mode, the offset is not always a 32-bit value. In a 32-bit operating system, user programs are always compiled into 32-bit code. Therefore, the assembler must work with the CPU to generate a 32-bit code indicating the offset.

Now the problem arises. When the CPU is changed from the real mode to the protection mode, how can we generate the correct code that allows the CPU to run?

There are two ways to solve this problem.

First, the Code executed in real mode should be compiled into a 16-bit offset code, and the code executed in protection mode should also be compiled into a 16-bit offset code, in addition, in the descriptor of the code segment, the code segment is set to 16 bits. The advantage of this method is that even if the assembler cannot generate 32-bit offset code, we can design programs in protection mode. The disadvantage of this method is that because the offset is 16 bits, the size of the code segment is limited.

Second, the Code executed in real mode must be compiled into a 16-bit offset code, and the code executed in protection mode must be compiled into a 32-bit offset code, in addition, in the descriptor of the code segment, the code segment is set to 32 bits. The advantage of this method is that the program can take full advantage of the strong functionality of the 32-bit processor. But this method has a problem: we inevitably need to jump from the 16-bit offset code to the 32-bit offset code. How can this be achieved? Because when writing the 16-bit offset code, we usually need to let the assembler generate the 16-bit offset code, but for the jump command that jumps to the 32-bit code segment, we also want the assembler to generate the 32-bit offset code. This is a contradiction. There are several ways to resolve this conflict. I know three methods: 1.
Instead of assembler code generation, programmers write machine code into code segments in situations defined by variables. This method is not helpful for assembler. 2. Some compilers allow programmers to specify the jump offset size and generate correct code, such as NASM, based on the programmer's designation. 3. Convert the assembler from the 16-bit compiling mode to the 32-bit compiling mode. Both na *** and gas support this method. However, some compilers only allow you to specify the compilation mode when defining segments, and the compilation mode cannot be changed in segments.

The following uses NASM as an example to illustrate how to convert a 16-bit code to a 32-bit code.

Section. Text

At this time, the CPU runs in the real mode

Bits 16; indicates that the compiling mode is 16 bits and the Code with 16 bits offset is generated.

; Code in real mode

; Load gdt. gdt contains the descriptor of this segment, which is 32-bit

To the protection mode, because this segment is described as 32-bit in gdt, so after the execution, the CPU considers all the offsets to be 32-bit.

Jmp dword cs_selector: PM; specifies that the offset is 32 bits, and cs_selector is the segment Selection Sub-of this code segment.

Bits 32; below the 32-bit compiling mode, all offsets are 32-bit

PM:

; Code

The following code has the same effect as the above Code.

Section. Text

At this time, the CPU runs in the real mode

Bits 16; indicates that the compiling mode is 16 bits and the Code with 16 bits offset is generated.

; Code in real mode

; Load gdt. gdt contains the descriptor of this segment, which is 32-bit

To the protection mode, because this segment is described as 32-bit in gdt, so after the execution, the CPU considers all the offsets to be 32-bit.

Bits 32; below the 32-bit compiling mode, all offsets are 32-bit

JMP cs_selector: PM; cs_selector is the segment selection child of this code segment.

PM:

; Code

The two examples above are the direct transformation from the real mode to the 32-bit protection mode, and the real mode code and the 32-bit protection mode code are in the same segment. There are other methods to implement this transformation, such:

1. The real-mode code and the 32-bit protection mode code are not in the same segment.

2. Use a 16-bit protection mode code for the transition. And so on. As long as you know the principle, the method is easy to understand.

From http://jacklin9.spaces.live.com/blog/cns! A891b52e1182afb2! 185. Entry

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.