Program loading and Execution (vi)--"x86 assembly language: From the actual mode to the protection mode" Reading notes 26

Source: Internet
Author: User
Tags scalar

Program loading and Execution (vi)--"x86 assembly language: From the actual mode to the protection mode" Reading notes 26

What can I learn from this article?

    • Glossary of conditions for NASM
    • When compiling with NASM, define macros with command-line options
    • Conditional statements for Makefile
    • overriding variable values in makefile on the Make command line
    • The 13th chapter exercises the solution
    • Review how to construct a stack segment descriptor

We went on to the last post and said.
In my revised document, a conditional compilation is used.
Like what:

%ifdef DEBUG    put_core_salt:  ;打印内核的符号    ...     ...    put_usr_salt:  ;打印用户的符号    ...    ... %endif

This is explained below.

1. Glossary of conditions

Similar to the C preprocessor, NASM allows a compilation of a source code only when a particular condition is satisfied.
Note that the preprocessor directives for the C language are # some of the commands that begin with the characters, nasm the preprocessor directives of the compiler % .

1.1 assembly only when a particular condition is met
%if<condition>    ;if <condition>满足时接下来的代码被汇编。    ......%elif<condition2>    if<condition>不满足,而<condition2>满足时,该段代码被汇编。    ......%else    ;当<condition>跟<condition2>都不满足时,该段代码被汇编。    ......%endif

%elseThe %elif clause is optional, and more than one clause can be used %elif .

1.2 Testing whether a single-line macro exists
%ifdef DEBUG    ...%endif

If we define a macro DEBUG , the code at the ellipsis will be assembled, otherwise it will not.

DEBUGFor example, you can use two methods to define a macro.

1.3 Defining macros directly in your code
%define DEBUG
1.4 through command-line options

When compiling the file, use the -d 宏名称 .

    -d DEBUG

For example:

 nasm c13_core.asm -o c13_core.bin -d DEBUG

Note: -d you can write a -D space between it and the macro name that follows it.
For example:

 nasm c13_core.asm -o c13_core.bin -dDEBUG
2. About Makefile

Because the conditional assembly was added, makefile is not the same as in the previous blog post.
Previous post address:
Program loading and Execution (v)--"x86 assembly language: From the actual mode to the protection mode" Reading notes 25

The modified makefile are as follows.

DEBUG =0BIN = C13_mbr.bin c13_core.bin c13.bin emptya_dir =/home/cjy/a.imgc_dir =/home/cjy/c.imgall:$(BIN). Phony:all cleanc13_mbr.bin:c13_mbr.asm NASM$<-O[email protected]Ddif=[email protected]of=$(A_dir) C13_core.bin:c13_core.asmifeq ($(DEBUG),1) NASM$<-O[email protected]-D DEBUGElseNasm$<-O[email protected]endif DDif=[email protected]of=$(C_dir) bs= +seek=1Conv=notruncc13.bin:c13.asm NASM$<-O[email protected]Ddif=[email protected]of=$(C_dir) bs= +seek= -Conv=notruncempty:diskdata.txt DDif=$<of=$(C_dir) bs= +seek= -Conv=notrunc Touch[email protected]Clean$(RM)$(BIN)
2.1 Article Statements

First, we define a variable (also called a macro) DEBUG and assign it a value of 0;
It is important to note the following lines:

ifeq ($(DEBUG),1)    $<[email protected] -DDEBUGelse    $<[email protected] endif

The conditional statement for Makefile is used here. When you perform make, different execution branches are selected according to the different conditions of the runtime.
In this example, when DEBUG the value of the variable is 1 o'clock, it executes nasm $< -o [email protected] -D DEBUG ;
When DEBUG the value of the variable is not 1 o'clock, it is executed nasm $< -o [email protected] ;

When we want to compile the source file with debug information, we can modify the value in makefile DEBUG to 1.

But is there a simpler way to do it?

2.2 Defining variables in the command line

When a variable (macro) definition in the command line conflicts with a definition in makefile, the definition in the command line prevails. So, we can add it when we execute make 变量=新值 to overwrite the value of the variable in the makefile file.

For the example in this article, in addition to modifying the value of 1 in Makefile DEBUG , there is another way to assign a value to a variable (macro) on the command line.


Note: When there are no spaces, the quotation marks can also be omitted. Because the macro definition must be passed as a single parameter, avoid using spaces, so it is more appropriate to use quotation marks.

3. The 13th Chapter Exercise solution

In this chapter, the user program gives only the recommended stack size, but does not provide stack space. Now, modify the kernel program and user program, change the user program to provide the stack space itself. Requirement: The stack segment must be defined after the user's program header.

Here, I give my own answers for the reference of the learners.

3.1 For source files c13.asmThe modification

There are two modifications. The first place is:

Because the stack space is provided by the user program, the assembly address and size of the stack must be specified so that the kernel program has enough information to create a stack segment descriptor for the user.

The second place is:

Since the topic already requires that the stack segment must be defined behind the user's program head, this is followed by a header definition stack space.

Small Episode
Compile this file, will error.

c13.asm:14error: division operator may only be applied to scalar valuesmake*** [c13.bin] 错误 1

Oh, why is that? I changed it.

stack_len        dd (stack_end-0)/(4*1024

Still reported the same mistake.
By looking at the information, I found some friends answered:

A label is a relocatable value--its value was modified by the Linker/loader. The difference between and labels (in the same section) are a scalar value, and NASM would work with it.

Well, since the difference between the two labels of the same section is scalar, I'm writing this:

 stack_len        dd (stack_end-stack_start)/(4*1024)  

In fact stack_start , before this marking is not, I have to do in order to do the difference value specifically added.
You also don't say, so the photo works, no error.

3.2 to the source file c13_core.asmThe modification

The code on the left (with the book Code), the kernel allocates memory for the user stack, and then computes the high-end physical address of the stack.
The Code on the right (exercise code), the kernel does not need to allocate memory, just remove the stack from the head of the start address, and then calculate the stack of high-end physical address.
This code is I wrote six months ago, but now read it also feel strange. Then explain the most critical 3 lines and deepen your memory.

469      mov edx,edi470      add edx,[edi+0x08]                ; 栈段起始的线性地址471      add eax,edx                       ; 得到栈的高端物理地址 

At this point, DS points to the 0-4GB data segment, and the content in EDI is the load address of the user program.
469:edx is the loading address of the user program;
470: Obtained from the user's head offset 0x08 section.stack.start , plus the user program's load address (EDX), the user stack is the starting address.
471: The base address in the stack descriptor should be the high-end physical address of the stack space, so add the stack size (in EAX).
If you do not understand why you are constructing a stack descriptor, you can refer to my blog post:
How to construct a stack segment descriptor

3.3 Verifying the program in Bochs

Our changes, right? "Practice is a real truth."

3.3.1 Verification Ideas

Because the stack space is provided by the user program, the kernel only creates the corresponding stack segment descriptor based on the header information. So what we want to verify is whether the stack descriptor and the user-defined stack match. In the above mentioned blog post, I have already elaborated how to construct the stack segment descriptor.

The header structure of the user program is as follows:

The user program of this experiment has 3 symbols, so the total head length is, 0x328 because the loading address of the user program is 0x100000 , so the starting address of the stack space is, 0x100328 and because the stack space size is defined as 0x1000(4KB) , so the high-end physical address of the stack space is 0x100328+0x1000=0x101328 ,
This should be the base address of the stack descriptor.

The valid segment bounds should be 0xFFFFFFFF-栈的大小(以字节为单位) , that 0xFFFFFFFF-0x1000=0xFFFFEFFF is, this should be the segment bounds in the stack segment descriptor.

3.3.2 Validation Results

Run the program in Bochs, run up, Ctrl + C Pause the program, enter info gdt the information that can view GTD. We see in:

The description of the Yellow dash matches our reasoning. So, our changes are correct.


Program loading and Execution (vi)--"x86 assembly language: From the actual mode to the protection mode" Reading notes 26

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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: and provide relevant evidence. A staff member will contact you within 5 working days.