Learn about x86/x64 together

Source: Internet
Author: User

When you encounter some underlying problems with the x86/x64 platform in actual work, you may often go through the manuals provided by Intel or AMD if you do not understand them, I need to refer to the Manual next time I encounter a problem. Now let's systematically learn the knowledge of X86/x64 systems, and then learn new things from the cold.

Lab importance

In the learning process, we aim to explore and rely on experiments. To thoroughly understand a knowledge point, it is obvious that the best method is demonstrated through testing experiments, and only through comprehensive testing is the most authentic and reliable. Some descriptions in the intel and AMD official manuals are obscure and may even cause errors. Therefore, the purpose of the test is to verify the authenticity and remove doubts.

It is an incorrect description in the intel64 software developer manual:

Description is part of the processing flow of the int command at the time of return: In IA-32e mode (the description includes the 64-Bit mode and compatibility mode) when the operand size is 32 or 16, only the 32-bit or 16-bit CS, EIP, and eflags values are pop. However, in 64-Bit mode, the processor will pop out the SS and ESP values unconditionally without relying on the operandsize value.

This description conflicts with the design in the x64 system (mainly based on the description in the amd64 Manual ). Therefore, when we fail to make an accurate judgment, we conduct a test experiment to verify that the following code is executed in 64-Bit mode:

MoV word [RSP], 0

MoV word [RSP + 2], kernel_cs

MoV word [RSP + 4], 46

MoV word [RSP + 6], 08f0h

MoV word [RSP + 8], 0a0h

DB 66 h

Iret

The result of this code execution is a 16-bit interrupt return, which is a 16-bit value in the stack:

This is the test result running on bochs. The RSP and SS values are not changed, and the SS and SP values are not pop. This is the simulation of bochs according to the process described in the intel64 manual.

Run the command on Vmware and the real machine to show that the SS value is 0a0h, the RSP value is 08f0h, and the processor has pop the SS and SP values from the stack.

However, this experiment can be written better and clearer. It is clear from this experiment that the description in the intel64 manual is not consistent with the facts. One of the purposes of this experiment is to verify authenticity.

The following section describes the interrupt priority:

"Each interrupt vector is an 8-bitvalue.
Interrupt-priority classIs the value of BITs 7:4 of theinterrupt vector. the lowest interrupt-priority class is 1 and the highest is15; interrupts with vectors in the range 0-15 (with interrupt-priority Class 0) are illegal and are never delivered.
Because vectors 0-31 are reserved fordedicated uses

The intel 64 and IA-32 ubuntures, software shocould configure interruptvectors to use interrupt-priority classes in the range 2-15.

Each interrupt-priority class encompasses 16 vectors. The amount of interrupts within an interrupt-priority class is determined by thevalue of bits of the vector number. The higher value of those bits,
Thehigher the priority within that interrupt-priority class. thus, each interruptvector comprises two parts, with the high 4 bits indicating itsinterrupt-priority class and the low 4 bits indicating its ranking within theinterrupt-priority class."

In this section, the 8-bit interrupt vector is divided into two parts for priority management. The 4-bit high is the priorityclass, and the 4-bit low is the priority ranking. We can think of it as a four-digit management level, and a four-digit lower is the ranking within the level. The vector value takes precedence.

However, the description here will confuse us: Is the ranking of the same class higher? The priority level is higher. In fact, it is not. The processor responds to the interrupt request by arbitration based on the value of vector: only a large priority class can respond.

As shown in another test experiment, when we set the value of TPR (task priority register) to 0x32, the priority class value of its interrupt threshold is 3 (Level 3rd ), at the same time, PPR (processor priority register) is also set to 0x32, and the PPR value is affected by TPR and ISR. The request can be responded only when the following conditions are met:

Vector [7: 4]> PPR [7: 4]

Therefore, when a interrupt request with Vector 0x33 is generated, it will be blocked and fail to respond. Only when the priority class value of vector is greater than 3 will it respond.

However, the description in the intel64 manual is not clear. We can only test and verify it through experiments, removing our confusions. This is the second role of the experiment.

We can imagine that most experiments are not suitable for testing on existing OS platforms due to OS restrictions. Therefore, we need to choose to test on the hosts machine.

You can select a running environment including a real machine, a bochs simulator, or a vmwarevm. You can select a USB flash drive, hard disk image file, or a floppy disk image file, and write your own boot program to guide the test. Depending on different media software formats: the USB flash drive and hard disk image files use the FAT32 format. The software image file can directly write the boot code into the MBR.

The above is the process for starting the boot program. In the FAT32 file format, our boot program is written to Sector 63 (starting from 0). After the BIOS reads the boot program into position 7c00h, continue loading the subsequent model of our experiment.

Take the format of the FAT32 file used by the U disk and hard disk image file as an example. The following figure shows the image file structure:

The common modules in our experiment are the boot module, setup module, lib16 module, protected module, lib32 module, and long module. The lib16 and lib32 modules are the library code, the protected module is the 32-bit protection mode to execute the code, and the long module is the 64-bit long module to execute the Code, while the boot module guides them, and the setup module switches to the protection mode.

After specifying the storage location of these modules in the image file, you need to write the code of these modules into the image file. You can use the most primitive method, that is, manually use hex software to merge and write data. This method is too troublesome.

Here we use the self-compiled merge tool merge to write data to the image file in batches based on its configuration file. The following is an example of the configuration file:

# Input file, input file offset, output file, output file offset, number of written blocks (1 block = 512 bytes)

# ***** Separate each item with commas ****

#

# Example:

#

# Module name offset output file name offset count (1 COUNT = 512 bytes)

#-------------------------------------------------

# Boot, 0, demo. IMG, 0, 1

# Setup, 0, demo. IMG, 1, 2

# Init, 0, demo. IMG, 3, 5

#

# Indicates:

# The Boot module writes demo. IMG data from Block 0 to Block 0, and writes 1 block.

# The setup module writes demo. IMG data from Block 0 at Block 1 and writes two blocks.

# The init module writes demo. IMG data from Block 0 to block 3, and writes 5 blocks.

# The configuration instances used in Chapter 2nd are as follows:

Boot, 0, demo. IMG, 0, 1

Each row has five projects separated by commas. They are: source file, source file start point, target file, target file start point, number of written parts (in 512 bytes ). To use the merge tool, we only need to execute the merge command in the command. Merge will help us batch write the corresponding location of the target file, saving trouble and avoiding errors.

Here, \. \ G is the device name of the USB flash drive. When the configuration file is added to the USB flash drive (the target file is the device name of the USB flash drive), We can insert the USB flash drive to the real machine for running.

Next, you need to write your own boot code. The following is a brief example:

 

; Set boot_seg Environment

MoV ax, CS

MoV ds, ax

MoV SS, ax

MoV es, ax

MoV sp, boot_seg
; Set the stack base
Boot_seg

Call clear_screen

MoV Si, hello

Call print_message

MoV Si, 20; Setup
The module is in Sector 20th.

MoV Di, setup_seg-2

Call load_module
; Use load_module ()
Read multiple sectors

MoV Si, setup_seg

Call print_message

MoV Si, word [load_message_table + eax * 2]

Call print_message

Next:

JMP $

In this boot example, the main task is to call the load_module () function to load a module. Next, call print_message () to print the information.

Finally, each test includes the source code file, bochs configuration file, merge tool configuration file, floppy disk image file (Demo. IMG), and hard disk image file (C. IMG ).

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.