Typo and formatting fixes in 2020/carlini/README
Some lists were did not come out as lists due to no blank lines in the markdown. Put a few code things between ``s. In one case I was unclear on what it should be but elsewhere in the document what I needed so all should be good there. Might have been one or two normal typos.
This commit is contained in:
1 parent
dd35e18751
commit
bb9af8908c
1 file changed
+18
-6
+18
-6
@@ -95,18 +95,27 @@ Here's (briefly) how it works.
|
|||||||
#### Preliminaries
|
#### Preliminaries
|
||||||
|
|
||||||
This program uses three printf format specifiers.
|
This program uses three printf format specifiers.
|
||||||
|
|
||||||
- `%d` takes an integer argument and prints it
|
- `%d` takes an integer argument and prints it
|
||||||
|
|
||||||
- `%s` takes a string argument and prints it
|
- `%s` takes a string argument and prints it
|
||||||
|
|
||||||
- `%n` takes a pointer and writes (!!) the number of bytes printed so far.
|
- `%n` takes a pointer and writes (!!) the number of bytes printed so far.
|
||||||
|
|
||||||
|
|
||||||
Okay, everyone probably knows this. Let's get a bit more advanced.
|
Okay, everyone probably knows this. Let's get a bit more advanced.
|
||||||
|
|
||||||
Format specifiers can take extra "arguments".
|
Format specifiers can take extra "arguments".
|
||||||
|
|
||||||
- `"%hhn"`: store the number of bytes written mod 256 to the char pointer
|
- `"%hhn"`: store the number of bytes written mod 256 to the char pointer
|
||||||
|
|
||||||
- `"%2$d"`: print argument 2 to printf (and not the sequentially next argument)
|
- `"%2$d"`: print argument 2 to printf (and not the sequentially next argument)
|
||||||
|
|
||||||
- `"%8d"`: pad the printed integer to 8 characters
|
- `"%8d"`: pad the printed integer to 8 characters
|
||||||
|
|
||||||
- `"%3$.*4$d"`: print argument 3 to printf with as many zeros as in argument 4.
|
- `"%3$.*4$d"`: print argument 3 to printf with as many zeros as in argument 4.
|
||||||
|
|
||||||
|
|
||||||
For example, the following expression
|
For example, the following expression
|
||||||
|
|
||||||
printf("%1$.*2$d%3$hhn", 5, 10, &x)
|
printf("%1$.*2$d%3$hhn", 5, 10, &x)
|
||||||
@@ -123,10 +132,13 @@ number of bytes written to x.
|
|||||||
Alright, now we can get to the real fun.
|
Alright, now we can get to the real fun.
|
||||||
|
|
||||||
We perform arbitrary computation with printf treating memory as a binary
|
We perform arbitrary computation with printf treating memory as a binary
|
||||||
array---one bit per pair of bytes:
|
array--one bit per pair of bytes:
|
||||||
|
|
||||||
- The zero bit is represented by the sequence `00 00`
|
- The zero bit is represented by the sequence `00 00`
|
||||||
|
|
||||||
- The one-bit is represented by the sequence `xx 00` where `xx` is any non-zero byte.
|
- The one-bit is represented by the sequence `xx 00` where `xx` is any non-zero byte.
|
||||||
|
|
||||||
|
|
||||||
We can use format strings to compute the OR/NOT of arbitrary "bits".
|
We can use format strings to compute the OR/NOT of arbitrary "bits".
|
||||||
|
|
||||||
We'll start with the simplest, OR:
|
We'll start with the simplest, OR:
|
||||||
@@ -181,10 +193,10 @@ the following expression
|
|||||||
|
|
||||||
where argument 1 is a pointer to a temporary variable followed by a null byte.
|
where argument 1 is a pointer to a temporary variable followed by a null byte.
|
||||||
|
|
||||||
This works because if the current count is 0 mod 256, then "%1$hhn" will write
|
This works because if the current count is 0 mod 256, then `"%1$hhn"` will write
|
||||||
zero to argument 1 and then "%1$s" will never emit any text. If, on the other
|
zero to argument 1 and then "%1$s" will never emit any text. If, on the other
|
||||||
hand, the count is not 0 mod 256, a length-1 string will be written to argument
|
hand, the count is not 0 mod 256, a length-1 string will be written to argument
|
||||||
1, and then "%1$s" will increment the count by one. By repeating this 256
|
1, and then `"%1$s"` will increment the count by one. By repeating this 256
|
||||||
times we're eventually going to reach 0 mod 256.
|
times we're eventually going to reach 0 mod 256.
|
||||||
|
|
||||||
Checking if there has been an invalid move is achieved similarly.
|
Checking if there has been an invalid move is achieved similarly.
|
||||||
@@ -200,7 +212,7 @@ which will, in effect, compute
|
|||||||
|
|
||||||
*r3 = (*r1) * 47 + (*r2) * 56 + 32
|
*r3 = (*r1) * 47 + (*r2) * 56 + 32
|
||||||
|
|
||||||
which will output ' ' if neither are true, 'X' if r1 is, or 'O' if r2 is.
|
which will output `' '` if neither are true, `'X'` if r1 is, or `'O'` if r2 is.
|
||||||
|
|
||||||
|
|
||||||
#### Further Obfuscations
|
#### Further Obfuscations
|
||||||
@@ -237,7 +249,7 @@ The byte `'I'` and `'S'` can always be the same, and we do the same for `'E'`/`'
|
|||||||
We do this same on-the-fly creation of the `scanf()` format string, but for a
|
We do this same on-the-fly creation of the `scanf()` format string, but for a
|
||||||
different reason. We first want to run `printf()` to show the first board, and
|
different reason. We first want to run `printf()` to show the first board, and
|
||||||
then alternate between runs to `scanf()` and `printf()` reading and then
|
then alternate between runs to `scanf()` and `printf()` reading and then
|
||||||
displaying moves. importantly, we *do not* want a final scanf when the game
|
displaying moves. Importantly, we *do not* want a final scanf when the game
|
||||||
ends. It should just exit.
|
ends. It should just exit.
|
||||||
|
|
||||||
One option would be to implement the logic as
|
One option would be to implement the logic as
|
||||||
@@ -262,7 +274,7 @@ statement, but it has the same effect.)
|
|||||||
Notice there is now no initial `printf()`. In order make sure the program doesn't
|
Notice there is now no initial `printf()`. In order make sure the program doesn't
|
||||||
block before the first `printf()`, but we initialize the `scanf()` format to the null
|
block before the first `printf()`, but we initialize the `scanf()` format to the null
|
||||||
string so that it returns right away without blocking. The first time the `printf()`
|
string so that it returns right away without blocking. The first time the `printf()`
|
||||||
call runs, it writes out "%hhd" to create the `scanf()` format string.
|
call runs, it writes out `"%hhd"` to create the `scanf()` format string.
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------
|
||||||
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
|
||||||
|
|||||||
Reference in new issue
Block a user