When I first started to study the course of microcomputer principle, I had a feeling that I couldn't start with assembly language programming. After a semester of practice, I am familiar with the assembly language. I want to organize an article to help the assembly Xiaobai who has just started.
1, Programming environment
Let's briefly mention the choice of programming environment. I prefer VScode. It is relatively convenient to install and has complete functions. You can complete the tab, fold the code, and easily view the contents of the register. Moreover, VScode software starts very fast and takes up acceptable storage space. It is not very bulky software!
Installation: VScode can be downloaded directly from the official website https://code.visualstudio.com/ Then install the MASM/TASM plug-in in VScode. Refer to other articles for the installation process, which will not be repeated here.
2, helloworld example and running
Create a new file, select the assembly(DOS) language, and then copy the following code:
TITLE HelloWorld DATA SEGMENT DispTEXT DB 10,'HelloWorld','$' DATA ENDS STACKS SEGMENT DW 80 DUP(?) ;duplicate 80 times,prepare 80Byte for stacks STACKS ENDS .486 CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA,SS:STACKS BEG: ;Initialization MOV AX,DATA MOV DS,AX ;where you can add your codes MOV AH,09H LEA DX,DispTEXT INT 21H ;Ending MOV AX,4C00H INT 21H CODE ENDS END BEG
In VScode, it should be like this:
Then right click and select "run the current program (assembly + link + run)", and then run the program
The operation results are shown in the figure below:
Note: Generally speaking, a complete program has three segments: data segment, stack segment and code segment.
Define variables in the data segment;
Stack space is defined in the stack segment (using "procedure", or both active PUSH and POP require a certain stack space)
Code snippet writing code:
The data area should be initialized at the beginning (standard format, generally written);
The end must end with MOV AX,4C00H INT 21H (just write it like this first, and the meaning will be understood later);
You can write code in the middle. When the code is long, it is recommended to use modular programming (using process PROC and MACRO. The difference between them will be described later).
The top TITLE is the program TITLE (can be written or not, it is the description of the program).
Notes are in English semicolons; start.
HelloWorld program uses the display of string, in which DispTEXT variable defines "10" at the beginning as the ASCII code of line feed character (the ASCII code of carriage return is not used, because carriage return in assembly language will display the character from the beginning of a line instead of line feed, which will be overwritten); The string must end with $, otherwise the program does not know where the display ends; Use the 09 function of INT21H (DOS) to display the string ending in $, and the first address of the string is pre stored in the DX register.
(if more commonly used DOS functions are not mentioned later, an issue may be issued)
3, Some troubleshooting (if the previous step runs correctly, you can skip it)
- If your environment does not support 32-bit registers, you can delete ". 486" and "USE16" in the code at the same time. The consequence is that 32-bit registers such as EAX, EBX, ECX and EDX are not allowed in the program, otherwise an error will be reported.
- Switch between doxbox and jsbox: switch in the "extension" on the left - the "extension settings" of MASM/TASM.
Generally speaking, doxbox is not much different from jsbox. I personally think the display interface of jsbox (left and right split screen display) is more comfortable, while dosbox generally displays the operation results in the form of pop-up window.
(the following figure shows the operation interface of jsbox:
Note: jsbox does not seem to support the 86H delay function of INT15H. If there is a problem with the operation result, you can try to change to dosbox.
MOV AH,86H MOV CX,200 MOV DX,0 ;CX,DX: Delay time (microseconds) INT 15H
4, Check the debug method of the register
As a beginner, you generally need to understand the operation mode of assembly language by looking at registers, and occasionally debug by looking at registers.
Right click and select "run current program (assembly + link + debugging)" to enter the debugging mode.
Select "view CPU" to view the register, as shown in the following figure:
Generally, use (Fn +) F8 for debugging (the process will be skipped)
If you want to enter the "process" to enter single-step debugging, you can use (Fn +) F7
End this commissioning (Fn +) F9
Note: if the mouse is restricted to the debugging area and cannot be moved, you can press the "Windows" button to let the mouse out~
5, Use of process PROC
The main program code of HelloWorld program is packaged with "process", and the code is as follows:
TITLE HelloWorld(withPROC) DATA SEGMENT DispTEXT DB 10,'HelloWorld','$' DATA ENDS STACKS SEGMENT DW 80 DUP(?) ;duplicate 80 times,prepare 80Byte for stacks STACKS ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKS BEG: ;Initialization MOV AX,DATA MOV DS,AX ;where you can add your codes CALL A10DISP ;call A10DISP to display "HelloWorld" ;Ending MOV AX,4C00H INT 21H ;define a process A10DISP PROC NEAR MOV AH,09H LEA DX,DispTEXT INT 21H RET A10DISP ENDP CODE ENDS END BEG
Note:
- The code in PROC must end with RET (return), otherwise the program cannot end normally when running and cannot return normally when calling multiple procedures;
- Calling procedure through CALL in the main program;
- Process calls need to use the stack, so stack errors (such as pushing 3 times in the process, but only popping 2 times) will cause process call errors, which shows that "the program runs away" and various strange jump errors occur;
- The process is generally named A10xxx, B10xxx, etc., which is convenient for classification and sorting;
- Generally, NEAR is enough for the process of a single program. FAR is only needed when multiple files call each other.
6, Use of MACRO
The main program code of HelloWorld program is packaged with "macro", and the code is as follows:
TITLE HelloWorld(withMACRO) ;define a macro DISPhw MACRO MOV AH,09H LEA DX,DispTEXT INT 21H ENDM DATA SEGMENT DispTEXT DB 10,'HelloWorld','$' DATA ENDS STACKS SEGMENT DW 80 DUP(?) ;duplicate 80 times,prepare 80Byte for stacks STACKS ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKS BEG: ;Initialization MOV AX,DATA MOV DS,AX ;where you can add your codes DISPhw ;Ending MOV AX,4C00H INT 21H CODE ENDS END BEG
Note:
- The definition of macros is generally placed at the beginning of the program, and the definition of each macro ends with ENDM;
- The macro is called directly through the name of the macro in the main program;
Differences between macros and procedures:
macro | process |
---|---|
The deployment is completed when the program is assembled | CALL completes the CALL when the program executes |
Pass and accept parameters directly | Pass parameters through the "register", "storage unit" stack |
Simplify the source program, not simplify the object code and increase the memory space | Shorten object code and save memory space |
No increase in execution time | Protect and restore the site and increase the time cost |
Therefore, when the subroutine itself is short and there are many parameters, it is more effective to use macro instructions;
Generally speaking, when the executable file is called, it is called in the form of procedure.
In modular programming, it is also recommended to call in the form of procedure.
Therefore, it can be seen that the more appropriate packaging method of HelloWorld program is "process" rather than "macro".
7, Complete program example
Simple bubble sorting (descending) and display
TITLE BUBBLESORT ;==============================================DATAsegment============================================================================================ DATA SEGMENT numbers DB 78,23,-12,0,-2,99,-11,-67,9,56,44 ;11 numbers DATA ENDS ;=================================================STACKS SEGMENT======================================================================= STACKS SEGMENT DW 128 DUP(?) ;duplicate 128 times,Preparation 128 Byte Space of STACKS ENDS ;===================================================CODE SEGMENT======================================================================= .486 CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA BEG: ;Initialization MOV AX,DATA MOV DS,AX A10MAIN PROC NEAR CALL A11BUBBLESORT CALL A12DISPLAY A10end: MOV AX,4C00H INT 21H A10MAIN ENDP ;===========================================PART1.BUBBLESORT================================================================================= A11BUBBLESORT PROC NEAR MOV CX,10 ;Record the number of external cycles L1: MOV DI,CX ;Record the number of current internal cycles MOV BX,0 ; Record the position of the currently compared number L2: MOV AL,numbers[BX] CMP AL,numbers[BX+1] JGE NEXT1 XCHG AL,numbers[BX+1] MOV numbers[BX],AL NEXT1: INC BX DEC DI CMP DI,0 JNE L2 LOOP L1 RET A11BUBBLESORT ENDP ;===========================================PART2.DISPLAY================================================================================= A12DISPLAY PROC NEAR MOV CX,11 MOV SI,0 Ldisp: MOV BX,10 PUSH BX MOV AX,0 MOV AL,numbers[SI] TEST AL,10000000B JZ LTRANSFORM ;Nonnegative number PUSH AX MOV AH,02H MOV DL,'-' INT 21H POP AX NEG AL LTRANSFORM: ;Convert numbers MOV DX,0 DIV BX ;DX,AX/BX = Business: AX,remainder: DX PUSH DX CMP AX,0 JNE LTRANSFORM DISP: POP DX CMP DX,BX JE NEXTNUM ;NEXT NUMBER MOV AH,02H ADD DL,30H INT 21H JMP DISP NEXTNUM: CMP SI,9 JA NEXT3 MOV AH,02H MOV DL,',' INT 21H NEXT3: INC SI LOOP Ldisp RET A12DISPLAY ENDP CODE ENDS END BEG