Assembly language_1 starts to write the program; LOOP instruction

start writing program

code example

After writing the assembly code, compile it with masm.exe program to generate .obj file, and then use link.exe to link to generate executable file.

The instructions we write include pseudo-instructions, instructions without corresponding machine codes, which are processed by the compiler; and assembly instructions, which are compiled into machine codes.

An assembler program consists of multiple segments (at least one), and we know that a segment is a logical division in units of 16B defined by ourselves.

Shaped like:

XXX segment #段开始
XXX ends 	#段结束
end			#汇编程序的结束标记

assume: Assume that a register is associated with a segment.

Writing program ideas:

  1. Define the segment.
abc segment

abc ends
end
  1. Write the implementation function
mov ax,2
add ax,ax
add ax,ax
add ax,ax
  1. Segments are associated with segment registers. We need to specify which segment register this segment is associated with.
assume cs:abc

DOS program running

DOS is a single-tasking operating system. If the P1 program is currently running and you want to switch to P2, P1 needs to load P2 into the memory and hand over the CPU control to P2, and then P2 can run. P1 suspends the operation until P2 finishes running and returns the control to P1. This process is called program return.

mov ax,4c00H
int 21H

These two instructions are the program return. This instruction is not executed by the compiler, but by the CPU.

Note that the previous instructions must be executed one by one with t, which means step into. int 21 instruction should be executed with p command, which means step over.

So the full content of the first program is:

assume cs:abc
abc segment
	mov ax,2
    add ax,ax
    add ax,ax
    add ax,ax
    mov ax,4c00H
	int 21H
abc ends
end

Name the .asm file.

The asm file is compiled with masm.exe, and the obj file is linked with link.exe, or directly compiled and linked with ml.

Compilation is to compile a file into a machine code file, and linking is to link it with related files and related libraries to generate an executable file.

Three questions of the soul:

  1. What program loads our program into the CPU and runs it? The command command line of DOS. If it is running with debug debugging, then it is debug to load the program and run it.
  2. How does the CPU enable programs to run? command Set CS:IP.
  3. Where do you go after running? Back to command.

Enter the file name and execute it directly. For example, the program we linked is called 1.exe, directly enter 1.exe to run. Enter debug 1.exeto enter debugging, which can be run line by line.

When you start debugging, you can find that other general-purpose registers are initialized to 0000, and only cx has a value. This is because the initial value of cx is the length of the program.

Then it can be found that CS=DS+0010H, the segment address difference is 0010H, and the physical address difference is 100H, which is 256, that is, the CPU automatically allocates 256 bytes to DS. The thing stored in these 256 bytes is called PSP, which is used by DOS to communicate with the program, just understand it. DS+256 is the CS that stores the program.

Therefore, the segment address SA of PSP can be obtained from DS. PSP physical address range is SA * 16+0~(SA+0010H) * 16+0-1.

(SA+16) * 16+0 starts to be the range of CS.

BS LOOP

Under normal circumstances mov ax, [0], it means to transfer the data of ds:0 to ax. But our compiler (ml) will translate it to mov ax, 0and generate an error.

Solution: In ml, we first pass the data into bx, and then mov ax, [bx]. or mov ax ds:[0]. Or write the program directly in debug, use a, the program written in this way will not have this problem.

assume cs:codesg
codesg segment
proj:   mov ax, 2000H
        mov ds, ax
        mov bx, 1000H
        mov ax, [bx]
        inc bx
        inc bx
        mov [bx], ax
        inc bx
        inc bx
        mov [bx], ax
        inc bx
        mov [bx], al
        inc bx
        mov [bx], al

        mov ax, 4C00H
        int 21H

codesg ends
end proj

isc: word +1.

The operation of the above function: assign the value at 21000H to ax, and then assign it to 21002H, 21004H...

For example, at the beginning, the value of 21000H is FF, and the value of 21001H is 46. The result of the assignment is:

image-20230411141015170

Just copy the value several times.

In assembly, a loop cycle can be realized through a register value, stop when the value = 0, and continue when ! = 0.

Example: Calculate 2^12.

assume cs:code
code segment
    mov ax, 2
    mov cx, 11
s: add ax, ax
    loop s
    mov ax, 4c00h
    int 21h
code ends
end

cx is the register used for loop, it will automatically loop every round –, when =0, it will exit the loop. Therefore, the number of assignments is repeated several times.

Use loop to loop through the contents of the s label name.

Example: 123*236.

Of course, it can be looped 236 times, but a better algorithm is to double ax continuously, and then loop the remaining times after counting the 128 bits of ax.

Pay attention to the relationship between the 16-bit register and the 8-bit data. If you pass it directly, you may report an error and you need to pass it to h or l.

There is another point to pay attention to: the data in the assembly cannot start with a letter. For example, if ffffh is written incorrectly, a 0:0ffffh should be added at the beginning.

Of course, there are too many loops in this way. We can use loop to omit it when writing code, but we still need to execute it line by line when debugging. Is there a shortcut?

image-20230411152703102

For example above, we can see that the 0014 offset address ends the loop.

g 0014por can finish the current cycle.

Example: ffff0:ffff11 12 addresses, add all the values ​​to ds.

We know that ds is a 16-bit register, and there are 12 bytes of data in these 12 addresses. If it is directly passed in, an error will occur.

Can all the low dl of ds be passed in? No, it will overflow.

So what to do? You can first pass each value into an intermediate 16-bit register, and that register is added to dx.

mov al, ds:[0]
mov ah, 0
add ds, ax

mov al, ds:[1]
mov ah, 0
add ds, ax

mov al, ds:[2]
mov ah, 0
add ds, ax

safe space

We assign values ​​casually, and accessing the operating system space is dangerous. This is the risk of directly manipulating the hardware.

0:200h to 0:2ffh in the memory space is safe space. Just in case, you can d first to see what's inside.

Example: Copy the value of ffff:0 11 to 0020:0 11.

assume cs:code
code segment
    mov bx,0
    mov cx,12
s:  mov ax,0ffffh
    mov ds,ax
    mov dl,[bx]
    mov ax,0020h
    mov ds,ax
    mov [bx],dl
    inc bx
    loop s

    mov ax, 4c00h
    int 21h
code ends
end

However, it is more troublesome to change = twice ds. We can use es to append register storage.

assume cs:code
code segment
    mov bx,0
    mov cx,12
    mov ax,0ffffh
    mov ds,ax
    mov ax,0020h
    mov es,ax
s:  mov dl,[bx]
    mov es:[bx],dl
    inc bx
    loop s

    mov ax, 4c00h
    int 21h
code ends
end

Guess you like

Origin blog.csdn.net/jtwqwq/article/details/130095943