Chapter 7 - X86 assembly language from real mode to protected mode

Chapter 7 Computation faster than Gaussian

7.3 Display strings

  • '1+2+3+...+100=' During the string compilation stage, the compiler will disassemble them to form individual bytes
  • Jump near start skips the data area without instructions
  • Lines 11~15 initialize data segment registers DSand additional segment registersES
  • Lines 18 to 28 are used to display character strings.
    First, the index register SI DSpoints to the first address of the character string to be displayed in the segment, that is, the assembly address represented by the label "message"
    uses another index register DI to point to the offset address 0 in the ES segment. , ES points to segment 0xB800
  • The display of strings depends on the loop. If loop is used, 20 lines of CXregisters are required, and the number of loops is string length = start-message 22 lines. First, the first character is obtained from the logical address of the data segment and transferred to the logical address to display the 24 lines of the buffer, and the DI Add one to the content to point to the attribute byte of the character in the display buffer, 0x07, 26 and 27 rows of white characters on a black background, register , add one to point to the next unit 28 rows of the original position and the target position , and execute the loop. First subtract one from the content, and then decide whether to loop according to whether it is zero. When it is zero, the display is complete.

    DS:SI
    ES:DI

    SIDI
    CXCXCX

7.4 Computing cumulative sums from 1 to 100

AX is cleared, 1 is passed to the register CX, and the accumulation starts. CXCompare with 100
to get cumulative sum in AX.

7.5 Accumulation and decomposition and display of each digit

Initialization of the stack and stack segments

To get the cumulative sum, each digit must be decomposed and prepared to be displayed on the screen.
Stored in the stack, the stack segment is pointed to by the segment register SS.
The stack pointer register is needed SPto indicate where the next data should be pushed onto the stack, or where data should be popped from the stack

40~42 lines of initialization SSand SPcontent

insert image description here

decompose the individual digits and push on the stack

The 44-line divisor is sent to BX
After each division, a judgment is made. If the quotient is 0, the decomposition process can be ended early, and the actual number of digits must be remembered. 45 line CXregisters are cleared to accumulate

Lines 47 to 53 are also the loop body, and each time it is executed, a digit is decomposed. One is added each time it is decomposed CX, indicating one more digit

Lines 48 and 49 will be DXcleared and AXtogether form the dividend of 32.

50 lines, or is not really an addition. This is because DLthe remainder is divided by 10 each time, so the high four bits must be 0x30, the low four bits are 0, and the high four bits are 3. So after or is equivalent to adding

On line 51, the push instruction pushes DXthe content onto the stack. The push instruction can only push one word in the 8086, but the subsequent 32-bit and 64-bit processors allow pushing words, double words, and quad words. So there must be keywords.

To execute the push instruction, first subtract the word length of the operand from the content of the SP, and then put the data to be pushed onto the stack at the SS:SPlocation of the logical address.

SP-2 is 0x0000-0x0002=0xFFFE, misalignment is ignored. Intel uses little endian, with low bytes at low addresses and high bytes at high addresses. The stack push operation is to advance from the high address end to the low address end.

insert image description here

Pop the stack and display the individual digits

Line 57, pop pops into DX, and then add the content of SP to the word length of the operand
. After performing the last pop, the content of SP is reset to 0

Learn more about the stack

The introduction of stack, push, and pop is just for the convenience of program development. Temporarily saving a value to the stack using the push instruction is the simplest and most trouble-free. Otherwise push ax can be

sub sp,2
mov bx,sp
mov [ss:bx],ax

pop ax similar

mov bx,sp
mox ax,[ss:bx]
add sp,2

If you want to save all temporary data in the data segment, then you must open up some space in the data segment, and maintain a pointer yourself to track the storage and retrieval of these data.

  • To keep the stack balanced, the value of SP before and after doing things must be the same, that is, the number of push and pop is equal.

  • The required stack space must be fully estimated. If the stack segment and the code segment belong to the same memory segment, the stack definition is too small, and the program is improperly written, and the stack may destroy useful data.

  • Please give an example why in the push operation, the stack pointer needs to subtract an offset first, and then store the data in the stack. In the stack operation, in the stack operation, the stack pointer needs to access the data in the stack first. , and then move the stack pointer up an offset.

    Suppose we have a stack. Initially, the stack pointer SP points to the memory address at the bottom of the stack, and two elements have been stored in the stack. At this point, we need to perform a push operation and a pop operation to explain why offset processing needs to be performed first in these two operations.

    Assuming that the data to be pushed is 0x1234, the size is 2 bytes, the push operation process is as follows:

    1. Subtract 2 from the stack pointer SP, which is the process of offset processing, let SP point to the free position on the top of the stack;
    2. Store the data 0x1234 in the memory location pointed to by the stack pointer SP;
    3. Point the stack pointer SP to the memory location stored in 0x1234, at this time SP points to the location of the top element of the stack.

    At this point the stack looks like this:

    stack top 0x1234
    element 2 0x5678
    element 1 0x9abc
    bottom of the stack SP points to

    Next, we perform a pop-up operation to pop the top element of the stack. The pop-up operation process is as follows:

    1. Access the memory location pointed to by the stack pointer SP, that is, access the top element of the stack 0x1234;
    2. Add 2 to the stack pointer SP, which is the process of offset processing, let SP point to the position of the next stack element;
    3. Return the stack top element 0x1234.

    At this point the stack looks like this:

    stack top 0x5678
    element 2 0x5678
    element 1 0x9abc
    bottom of the stack SP points to

    It can be seen that when performing stack push and pop operations, offset processing needs to be performed first, so as to ensure the correctness of the stack pointer and the consistency of data in the stack.

7.6 Compile and run the program

The command to view the stack in Bochs is "print-stack", which displays 16 characters in the current stack by default

7.7 Addressing Mode of 8086 Processor

The addressing mode is how to find the data to be operated, and how to find the place to store the result of the operation (based on 16-bit processor)

  1. register addressing
mov ax,cx
add bx,0xf000
inc dx
  1. immediate (number) addressing
add bx,0xf000
mov dx,label_a

The label is converted into an immediate value at the compilation stage
The operand of immediate addressing is located in the instruction and is part of the instruction

  1. Memory addressing
    The segment address is provided by one of the 4 segment registers, and the offset address is provided by the instruction
    Memory addressing is actually to find the offset address, which is called the effective address, that is
    , how to provide the offset address in the instruction, Used by the processor to access memory
  • direct addressing
mov ax,[0x5c0f]
add word [0x0230],0x5000
xor byte [es:label_b],0x05
  • Base addressing
    Base addressing is to use the base register BXor BPto provide the offset address in the address part of the instruction
mov [bx],dx //将DS的内容左移4位,加上基址寄存器BX的内容
add byte [bx-2],0x55  //可加减一个偏移量不改变bx内容
mov ax,[bp] //该寄存器的默认段寄存器是SS,常用于访问栈

For function calls in high-level languages, all parameters are on the stack. In order to be able to access the parameters that are pressed at the bottom of the stack, it needs to be used BP.

insert image description here

  • Indexed addressing The
    addressing mode uses index registers (index registers) SI and DI
  • base indexed addressing

​ Reversely arrange the string db 'abcdef to z' in place

	mov bx,string 
	mov si,0
	mov di,25
order:
	mov ah,[bx+si]
	mov al,[bx+di]
	mov [bx+si],al
	mov [bx+di],ah
	
	inc si
	dec di 
	cmp si,di
	jl order

Compilation of this chapter:

                                               ;代码清单7-1
                                               ;文件名:c07_mbr.asm
                                               ;文件说明:硬盘主引导扇区代码
                                               ;创建日期:2011-4-13 18:02                             
     00000000 E90E00                           jmp near start
                                      	
     00000003 312B322B332B2E2E2E-      message db '1+2+3+...+100='
     0000000C 2B3130303D         
                                              
                                       start:
     00000011 B8C007                           mov ax,0x7c0           ;设置数据段的段基地址 
     00000014 8ED8                             mov ds,ax
                                      
     00000016 B800B8                           mov ax,0xb800          ;设置附加段基址到显示缓冲区
     00000019 8EC0                             mov es,ax
                                      
                                               ;以下显示字符串 
     0000001B BE[0300]                         mov si,message          
     0000001E BF0000                           mov di,0
     00000021 B90E00                           mov cx,start-message
                                           @g:
     00000024 8A04                             mov al,[si]
     00000026 268805                           mov [es:di],al
     00000029 47                               inc di
     0000002A 26C60507                         mov byte [es:di],0x07
     0000002E 47                               inc di
     0000002F 46                               inc si
     00000030 E2F2                             loop @g
                                      
                                               ;以下计算1到100的和 
     00000032 31C0                             xor ax,ax
     00000034 B90100                           mov cx,1
                                           @f:
     00000037 01C8                             add ax,cx
     00000039 41                               inc cx
     0000003A 83F964                           cmp cx,100
     0000003D 7EF8                             jle @f
                                      
                                               ;以下计算累加和的每个数位 
     0000003F 31C9                             xor cx,cx              ;设置堆栈段的段基地址
     00000041 8ED1                             mov ss,cx
     00000043 89CC                             mov sp,cx
                                      
     00000045 BB0A00                           mov bx,10
     00000048 31C9                             xor cx,cx
                                           @d:
     0000004A 41                               inc cx
     0000004B 31D2                             xor dx,dx
     0000004D F7F3                             div bx
     0000004F 80CA30                           or dl,0x30
     00000052 52                               push dx
     00000053 83F800                           cmp ax,0
     00000056 75F2                             jne @d
                                      
                                               ;以下显示各个数位 
                                           @a:
     00000058 5A                               pop dx
     00000059 268815                           mov [es:di],dl
     0000005C 47                               inc di
     0000005D 26C60507                         mov byte [es:di],0x07
     00000061 47                               inc di
     00000062 E2F4                             loop @a
                                             
     00000064 E9FDFF                           jmp near $ 
                                             
                                      
     00000067 00<rept>                times 510-($-$$) db 0
     000001FE 55AA                                     db 0x55,0xaa

Guess you like

Origin blog.csdn.net/weixin_61631200/article/details/129501043