diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2d675ce..7f1da31 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,3 +14,4 @@ Special thanks to all the people who helped to develop this project: - [awatne](https://github.com/awatne) - [rcalixte](https://github.com/rcalixte) - [realy8v](https://github.com/realy8v) +- [dajiaohuang](https://github.com/dajiaohuang) diff --git a/content/asm_2.md b/content/asm_2.md index bac2d2f..babfbe4 100644 --- a/content/asm_2.md +++ b/content/asm_2.md @@ -257,7 +257,7 @@ bar: mov r9d, 6 ;; Push the fifth argument to the r8d register mov r8d, 5 - ;; Push the fourth argument to the exc register + ;; Push the fourth argument to the ecx register mov ecx, 4 ;; Push the third argument to the edx register mov edx, 3 diff --git a/content/asm_3.md b/content/asm_3.md index 111e89b..54af3e8 100644 --- a/content/asm_3.md +++ b/content/asm_3.md @@ -42,7 +42,7 @@ These registers are: - `rdi` - used to pass the first argument to a function. - `rsi` - used to pass the second argument to a function. - `rdx` - used to pass the third argument to a function. -- `r10` - used to pass the fourth argument to a function. +- `rcx` - used to pass the fourth argument to a function. - `r8` - used to pass the fifth argument to a function. - `r9` - used to pass the sixth argument to a function. @@ -116,7 +116,7 @@ foo: ;; Function epilogue mov rsp, rbp - pop + pop rbp ``` These two can be replaced with special instructions: `enter N, 0` and `leave`. The `enter` instruction has two operands: diff --git a/content/asm_4.md b/content/asm_4.md index 34ba089..e105c01 100644 --- a/content/asm_4.md +++ b/content/asm_4.md @@ -96,9 +96,9 @@ The logical instructions are used to execute [logical operations](https://en.wik - `and` - The instruction takes two operands and performs the logical *and* operation on them. - `or` - The instruction takes two operands and performs the logical *or* operation on them. - `xor` - The instruction takes two operands and performs the logical *xor* operation on them. -- `not` - The instruction takes two operands and performs the logical *not* operation on them. +- `not` - The instruction takes one operand and inverts all of its bits. -The result is stored in the first operand. +The result of the `and`, `or`, and `xor` instructions is stored in the first operand. For example: @@ -236,7 +236,7 @@ reverseStringAndPrint: jmp reverseStringAndPrint ``` -At the beginning of this procedure, we compare the value pointed to by the `rsi` register with `0`. Here, `0` means the end of the input string, as each string is [NUL-terminated](https://en.wikipedia.org/wiki/Null-terminated_string). If we reach the end of the input string, we jump to the `reverseString` label, which will reverse our string. Otherwise, we take characters one by one from the input string using the `loadsb` instruction and store them on the stack. It is very convenient to store the string's characters on the stack. Since the stack has a [LIFO](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) access pattern, we will pop the characters from the stack in reverse order — from the end to the beginning. This allows us to reverse the string. This procedure is [recursive](https://en.wikipedia.org/wiki/Recursion) and will be called repeatedly until we reach the end of the string. +At the beginning of this procedure, we compare the value pointed to by the `rsi` register with `0`. Here, `0` means the end of the input string, as each string is [NUL-terminated](https://en.wikipedia.org/wiki/Null-terminated_string). If we reach the end of the input string, we jump to the `reverseString` label, which will reverse our string. Otherwise, we take characters one by one from the input string using the `lodsb` instruction and store them on the stack. It is very convenient to store the string's characters on the stack. Since the stack has a [LIFO](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) access pattern, we will pop the characters from the stack in reverse order — from the end to the beginning. This allows us to reverse the string. This procedure is [recursive](https://en.wikipedia.org/wiki/Recursion) and will be called repeatedly until we reach the end of the string. After reaching the end of the string, we can reverse it. We will do it using the following code: diff --git a/content/asm_5.md b/content/asm_5.md index 8bfea4e..eefcfa3 100644 --- a/content/asm_5.md +++ b/content/asm_5.md @@ -42,7 +42,7 @@ This is very similar to a usual C-like macro that we can define using the `#defi ;; ... ;; Pointer to the number of command line arguments -define argc [rsp] +%define argc [rsp] ;; Pointer to argv[0] (program name) %define argv0 qword [rsp + 8] @@ -436,10 +436,10 @@ REPX {psrlw x, 8}, m0, m1, m2, m3 It will be expanded to: ```assembly -pmulhuw m0, m7 -pmulhuw m1, m7 -pmulhuw m2, m7 -pmulhuw m3, m7 +psrlw m0, 8 +psrlw m1, 8 +psrlw m2, 8 +psrlw m3, 8 ``` We’ve just explored a real-world assembly code! 🎉 🎉 🎉 diff --git a/content/asm_6.md b/content/asm_6.md index df068a2..141bdb4 100644 --- a/content/asm_6.md +++ b/content/asm_6.md @@ -174,7 +174,7 @@ All of these instructions expect two operands to execute the given operation of ### Floating-point control instructions -As we already know, the main goal of these instructions is to manage the control flow of our programs. For integer comparisons, we used the `cmp` instruction. However, this instruction does not work with floating-point values, even though the result of the comparison is controlled by the same `rflags` registers that we saw in the [Data manipulation](./asm_4.md#control-transfer-instructions) chapter. The general instruction to compare floating-point numbers is `cmpss`. Instead of setting the value of the flag based on the result comparison, the instruction stores the result of the comparison in the destination register. +As we already know, the main goal of these instructions is to manage the control flow of our programs. For integer comparisons, we used the `cmp` instruction. However, this instruction does not work with floating-point values: unlike an integer comparison, whose result is recorded in the `rflags` register, a floating-point comparison stores its result in the destination register. The general instruction to compare floating-point numbers is `cmpss`. Instead of setting the value of the flag based on the result comparison, the instruction stores the result of the comparison in the destination register. For example: @@ -194,7 +194,7 @@ The third operand of the instruction identifies the operator: | 4 | != | | 5 | >= | | 6 | > | -| 7 | Checks that both operands are [Nan](https://en.wikipedia.org/wiki/NaN) | +| 7 | Checks that neither operand is [NaN](https://en.wikipedia.org/wiki/NaN) | ## Example diff --git a/content/asm_7.md b/content/asm_7.md index ea57716..3130254 100644 --- a/content/asm_7.md +++ b/content/asm_7.md @@ -34,7 +34,7 @@ _start: mov rdi, 1 ;; Set the second argument of `sys_write` to the reference of the `msg` variable. mov rsi, msg - ;; Set the third argument of `sys_write` to the length of the `msg` variable's value (13 bytes). + ;; Set the third argument of `sys_write` to the length of the `msg` variable's value (14 bytes). mov rdx, 14 ;; Call the `sys_write` system call. syscall