First article on compilation:
love, love, this register is a bit
Hello everyone, I am a programmer cxuan! We learned about the basic registers in the last article. In this article, let's take a look at the actual operation.
Original link: you how to assemble Debug
We will use many Debug commands in the future, let's get familiar with them first.
What is Debug
Debug is a function provided by Windows / Dos operating system. Using Debug allows us to easily view the values of various registers and memory conditions of the CPU, and it is convenient for us to debug instructions and track the running process of the program.
Next, we will use many debug commands, but the premise of using these commands is that you need to install debug on your computer, which can be installed on both Windows and Mac. I have found the link for you. Ah, forgot to say, we are using Dos box to simulate the operating environment of assembly.
Portal (both Mac and Windows): https://www.dosbox.com/download.php?main=1
Open DosBox after the download is complete, and it looks like this after opening.
At this point, what we enter the debug command should prompt
Because we have not connected and mounted yet, at this time we execute
mount c D:\debug
When executing this command, you need to create a debug folder under D drive now, and then we mount it under debug.
And execute C:
switch to the C drive path.
At this point we can execute the debug command.
One thing to note here, when I set up the Debug environment under the Windows 10 system, I entered debug after the mount was completed, and it still prompted Illegal command:debug . At this time, you need to download a debug.exe again, and I will download it if you are considerate I gave you the address.
Download : 1619b07c37d879 https://pan.baidu.com/s/177arSA34plWqV-iyffWpEw#list/path=%2F Password: 3akd
You need to download the debug.exe inside, and then put it under the path you mounted. Here, the path I mounted is the debug folder under the D drive.
After the placement is complete, enter debug again.
Because the above commands are executed every time Dosbox is opened, which is really annoying, so what should I do? An easy way is to find it under the Dosbox installation path
After opening, type at the end
It's OK. Next time you open Dosbox directly, these three commands will be executed by default. So far, all the problems I encountered when building Dosbox.
Debug actual combat
You can learn to use Debug if you play assembly. Debug is a debugging program . Through Debug, we can see the memory value, trace the stack situation, see the contents of the register, etc., and also help us better Understand the assembly code, so learn to Debug, is very important, , this is an indispensable hands-on ability.
Below we will use several Debug commands, here is a brief introduction.
<img src="https://tva1.sinaimg.cn/large/008i3skNly1gwiil6fj2qj31040rm76a.jpg" alt="image-20211117222634775" style="zoom:50%;" />
There are many Debug commands, but the commonly used ones are generally the above ones.
Okay, now we go directly to the topic and start the formal Debug operation on Dosbox. First, open Dosbox.
Um. . . . . . We have opened this interface many times.
What if I write an order? Well, I haven't demonstrated it before, here comes it!
Debug -r
, use 1619b07c37d999 Debug -r to view and modify the contents of the CPU registers.
<img src="https://tva1.sinaimg.cn/large/008i3skNly1gwij6myjunj30b30ayt99.jpg" alt="image-20211117224711832" style="zoom:67%;" />
View the contents of the register.
Here you need to pay attention to the case of -r. Debug -r is to view the contents of the register. And -R is an invalid command.
The above figure lists a lot of registers. You may feel that you have no way to start. Don’t mess up. Let’s start with the most basic ones, namely CS and IP. CS (Code Segment) is the code segment register, which is generally called the segment base address. It can be considered as the entry point of program access. The CPU needs to find from CS where to start fetching the instruction, but we still don’t know which section to fetch. At this time, the role of IP is reflected. IP (Instruction Pointer) is the instruction The pointer register, also called the offset address, will tell us which segment address to take from the segment base address.
You can use the segment base address: offset address to determine the specified address in the memory.
Here we just briefly talk about the concepts of these two registers. To understand the specific functions of these two registers, you can read the author’s previous article
Use -r to modify the contents of the register, as shown below
The general format of -r register , and then the system will prompt a colon, and the following is the content you want to modify.
Debug -d
Use the -d command to view the contents of the memory.
By default, the output memory value starts with the address of CS:IP. Since the default value of CS is 073F and the default value of IP is 0100, the memory value of -d is 073F:0100.
There are many formats of -d, and only a few commonly used formats are introduced below.
The format like -d 1000:0 -d segment base address offset address can produce the following output.
As shown in the figure above, Debug will list the contents of the specified memory unit. Each 00 in the above figure represents 8 digits. If it is 4A, then the expansion of these eight digits is 0010 1011. Each row has 16 8-bits, so a 128-bit memory address is formed.
Why are they all 00? Because the value of the memory unit has not been rewritten. To put it bluntly, there is no value in this memory area. How to rewrite it and reclaim it later.
-
in the middle of each line. This is set for the convenience of our reading. There are 8 memory units before and after the-sign, which is convenient for viewing.
The few on the right... indicate the ASCII code characters that can be displayed in each memory unit. Because the memory has no value, there is no corresponding ASCII code. We can count, there are 16 in each line. This means that each 00 corresponds to an ASCII code.
We can use the -d segment base address: starting offset address format of -d 1000:9 to display the number of digits from 1000.
Debug starts from 1000:9 and continues to 1000:88, a total of 128 bytes, and the contents of 1000:0 ~ 1000:8 in the first line are not displayed.
You can also use -d 1000:0 9 -d segment base address: start offset address end offset address format to output.
You can also use the -d offset address to view the memory value without specifying the segment base address.
Debug -e
All of the above is to view the value of the specified location or area in the memory. Next, we are going to rewrite the memory value.
Use -e
to rewrite the memory value. For example, if we want to rewrite the content in 1000:0 ~ 1000:f, we can use -e 1000:0 0 1 2 3 4 5 6 7 8 9 0 abcdef this way, as shown in the figure below .
It should be noted here that when rewriting -e, there is a space in each value. If there is no space, it will be treated as a memory value.
Then use -d 1000:0 to see the memory value we just rewritten.
You can also use the way of asking questions to modify the contents of the memory cells starting from a certain address one by one.
Still use 1000:100 as an example, output -e 1000:100 and press Enter.
As shown in the figure above, we can see that we first entered the command -e 1000:100 once, and then pressed the Enter key.
Note that if you press the Enter key here, it is equivalent to the entire -e rewriting process has been completed.
If you want to continue to rewrite the value in the memory later, you need to press the space bar.
We rewrite the memory value after 1000:100, and then use -d 1000:100 to see if the content we rewritten takes effect.
The -e command can also support writing characters. For example, we can start writing values and characters to 1000:0, -e 1000:0 1'a' 2'b' e'c'.
As shown in the figure above, when we write characters'a''b''c' into the memory, they will be automatically converted to ASCII code for storage, and the character just written can be found on the far right.
Debug -u
How to write a piece of machine code into the memory? For example, we want to write a piece of machine code in memory.
We can use -e to write, write the machine code b8 01 00 b9 02 00 01 c8 to the memory, as shown below
After we use -e to write, we use -d to view the memory value, we can find the value we just wrote, but we can't see the machine code, so how do we look at the machine code?
Don't worry, there is also a -u command, this is to look at the machine code, as shown in the figure below, we use the -u command to display the machine code we wrote.
You can see that the memory address of 1000:0000 ~ 1000:0006 makes us write the machine code. The -u command is to translate the content of the memory unit into assembly instructions and display it.
The output of -u is displayed in three parts:
- The leftmost is the address of each machine instruction;
- The middle is the machine instruction;
- On the far right is the assembly instructions executed by the machine instructions.
The machine instruction composed of the written machine code B8 01 00 is stored at 1000:0, and the corresponding assembly instruction is MOV AX,0001.
Stored at 1000:0003 is the machine instruction composed of the written machine code B9 02 00, and the corresponding assembly instruction is MOV CX,0002.
Stored at 1000:0006 is the machine instruction composed of the written machine code C1 C8, and the corresponding assembly instruction is add ax, cx.
Debug -t
The series of instructions introduced above, including the Debug-e machine code we mentioned above, are all written to the memory, so how to execute these instructions?
We can use Debug -t to execute the written instructions. Use Debug -t to execute the instruction pointed to by CS:IP.
Since -t can execute the command pointed to from CS:IP, it is necessary for us to point CS:IP to 1000:0 (because we wrote the command at 1000:0 earlier).
First, we need to execute -r cs 1000 and -r ip 0 to assign CS:IP to 1000:0.
Then execute the -t command, the following figure is a screenshot of the executed command.
It can be seen that after the -t instruction is executed, the MOV AX,0001 instruction is executed, and the current content of the AX register becomes 0001. This assembly instruction means to move 0001 to the AX register.
After continuing to execute -t, we can see the register changes.
Debug -a
After all, machine instructions are not so easy to understand and writing is very inconvenient, so is there any way to support us to write assembly instructions directly? Really, Debug provides -a this way to realize the writing of assembly instructions. As shown below
As you can see, we used the -a command to write 1000:0, respectively input mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx add ax,ax instructions, and then press back The car is determined to be executed.
We can use -d 1000:0 f to see the f-th memory instruction starting from offset address 0 (because the maximum write address is only f).
Why does 1000:000F in the above figure have a value, because we have already executed this write above.
In addition, use -a to start inputting instructions from a preset address.
Summarize
Today I talked with you about the basic usage of Debug, mainly including
- -r View and modify the contents of the register
- -d View instructions in memory
- -e modify the contents of the memory
- -u can interpret the contents of the memory as machine instructions and corresponding assembly instructions
- -t execute the command at CS:IP
- -a Write content to memory in assembly form
There are many options for assembly instructions. The instructions described above are frequently used instructions, and these instructions must be used proficiently.
Finally, I recommend my own Github , which contains a lot of hardcore articles, which will definitely help you.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。