Skip to content

Commit

Permalink
writing, endiannes completed
Browse files Browse the repository at this point in the history
  • Loading branch information
robalb committed Jul 17, 2024
1 parent 09e59b4 commit b177be6
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 88 deletions.
95 changes: 95 additions & 0 deletions astro-website/src/components/EndiannessEmbed.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script>
/**
* This is an interactive element specifically created
* for the moving-data-x64 article.
* It showcases how the "mov ptr [src] dest" x86-64
* assembly syntax works, wiht a live example
*
*/
import GdbEmbed from './GdbEmbed.svelte'
let data = [0, 0, 0, 0, 0xca, 0xfe, 0xba, 0xbe];
let startAddress = 0;
let imm = ""
let error = ""
let immBytes = []
$: {
let [r, err] = convertImmediateValue(imm);
immBytes = r
error = err
}
function bigintToBytesLE(bigIntNumber) {
let bytes = [];
for (let i = 0; i < 8; i++) {
bytes.push(Number(bigIntNumber & BigInt(0xff)));
bigIntNumber = bigIntNumber >> BigInt(8);
}
return bytes;
}
function convertImmediateValue(input) {
// Define the maximum value for a 64-bit unsigned integer
const MAX_64BIT = BigInt("0xFFFFFFFFFFFFFFFF");
let result = [0, ""];
if(input.length == 0){
result[1] = " ● missing number"
}
try {
let value = BigInt(input);
if (value <= MAX_64BIT) {
result[0] = bigintToBytesLE(value);
} else {
result[1] = " ● The provided number is too large";
}
} catch (e) {
result[1] = " ● Invalid input format, not a number";
}
return result;
}
let start_addr = 0x20
function init(){
data = Array(14*8).fill(0)
let text = "Example text"
text.split("").forEach((c,i) => data[i] = c.charCodeAt(0))
imm = "0xfeedc0de12345678"
error = ""
}
init();
function run(){
console.log({imm, immBytes})
for(let i=0; i< immBytes.length; i++)
data[start_addr+i] = immBytes[i];
data = data;
}
</script>

<GdbEmbed
on:runClick={run}
on:resetClick={init}
registersPanel={false}
{data}
showAscii={true}
{startAddress}
>
mov rbx, <span class="token number">
<input type="text" bind:value={imm} />
</span> <span class:error={error.length}> {error}</span>
mov rax, <span class="token number">0x20</span>
mov qword ptr [rax], rbx
</GdbEmbed>

<style>
.error {
background-color: rgb(105,51,61);
color: #ffbcbc;
}
</style>

9 changes: 5 additions & 4 deletions astro-website/src/components/PtrSyntaxEmbed.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ let start_addr = 0x20
let color_regions = {}
function init(){
data = [
80, 97, 103, 101, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 81, 85, 85, 85, 85, 0, 0, 64, 220, 255, 255, 1, 0, 0, 0, 88, 220, 255, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 4, 190, 18, 120, 233, 111, 224, 88, 220, 255, 255, 255, 127, 0, 0, 233, 81, 85, 85, 85, 85, 0, 0, 152, 125, 85, 85, 85, 85, 0, 0, 64, 208, 255, 247, 255, 127, 0, 0, 232, 4, 28, 164, 135, 22, 144, 31,
0, 0, 0, 0, 0, 0, 0, 0
]
// data = [
// 80, 97, 103, 101, 32, 110, 111, 116, 32, 102, 111, 117, 110, 100, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 81, 85, 85, 85, 85, 0, 0, 64, 220, 255, 255, 1, 0, 0, 0, 88, 220, 255, 255, 255, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 4, 190, 18, 120, 233, 111, 224, 88, 220, 255, 255, 255, 127, 0, 0, 233, 81, 85, 85, 85, 85, 0, 0, 152, 125, 85, 85, 85, 85, 0, 0, 64, 208, 255, 247, 255, 127, 0, 0, 232, 4, 28, 164, 135, 22, 144, 31,
// 0, 0, 0, 0, 0, 0, 0, 0
// ]
data = Array(14*8).fill(0)
selected = options[0];
color_regions = {}
updateRegions()
Expand Down
37 changes: 31 additions & 6 deletions astro-website/src/pages/posts/moving-data-x64.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SliderHexdump from '../../components/SliderHexdump.svelte'
import RegistersTable from '../../components/RegistersTable.svelte'
import PtrSyntaxEmbed from '../../components/PtrSyntaxEmbed.svelte'
import StackEmbed from '../../components/StackEmbed.svelte'
import EndiannessEmbed from '../../components/EndiannessEmbed.svelte'

It's often said that assembly language is complex. Most people are scared of it, everyone avoids it.
After all, there's a reason why high-level languages and compilers were invented, right?<br/>
Expand Down Expand Up @@ -90,10 +91,9 @@ contains all the names that you will encounter while working with the x86-64 arc
There are a lot of different ways to encode text, and I recommend that you
read the [bare minimum foundamentals](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/)
, it's a very interesting topic in itself.
But in this article we'll only focus on ASCII encoding, which is extremely simple.
All you need to know is this:
In this article however we'll only focus on ASCII encoding, which is extremely simple:

In ASCII, text is stored as a seqence of bytes. every byte represents a character,
All you need to know is that text is stored as a seqence of bytes. every byte represents a character,
so there are `127` possible characters between numbers, english letters and puctuation.
You can find a table of all the ascii characters in the
[linux man pages](https://man.archlinux.org/man/core/man-pages/ascii.7.en).
Expand Down Expand Up @@ -215,16 +215,41 @@ but we choose that number carefully to hide the issue. In the next example, you
You can enter either Decimal or Hex numbers, prefix Hex numbers with `0x`.<br/>
Can you spot the issue?

<PtrSyntaxEmbed client:load />
<EndiannessEmbed client:load /><br/>

You should have noticed that the bytes that compose a number are stored
in reverse order compared to the way we read and write them.
Both humans and computers use a positional number system to represent integers, where
the same digit has a different weight depending on its position.<br/>
When we represent numbers, we put the most significant digits to the left:

```
1337
| |
| Least significant digit
Most significant digit
0xcafebabe
| |
| Least significant byte
Most significant byte
```
In other words, we write the most significant value first.
In little endian architectures the least significant value is written first instead.

This topic is explained in details on [wikipedia](https://en.wikipedia.org/wiki/Endianness), with some
useful diagrams that will solve any doubts you might have.<br/>
Endianness is only related to the way the processor handles numbers. Note how
other kind of data, such as text, is usually encoded in the same order as you would expect.

### the stack

x64, like most architectures, has the concept of stack: an area in memory pointed
by the special register `rsp`.<br/>
You can add or remove elements from the top of the stack by using the
`push` and `pop` instructions. This is the most common interaction, but it's also valid to directly adjust the value of `rsp`.
This interactive example allows you to experiment with `push` and `pop`.
The stack area is highlighted in blue and displayed below, togehther with the contents of the `rsp` and `rax` registers.
In this interactive example
the stack area is highlighted in blue, and the contents of the `rsp` and `rax` registers are displayed.

<StackEmbed client:load /><br/>

Expand Down
78 changes: 0 additions & 78 deletions astro-website/src/pages/posts/style-tests.mdx

This file was deleted.

0 comments on commit b177be6

Please sign in to comment.