---
# System prepended metadata

title: Uxntal Programming Zero2Hero ~共筆~

---

# Uxntal Programming Zero2Hero ~共筆~

一起來學Uxntal吧！

什麼是Uxntal呢？Uxn是什麼？如果你還不知道，你應該參考這篇共筆：

* https://hackmd.io/@ljcucc/uxn

這篇筆記有很大一部分是參考自：https://compudanzas.net/uxn_tutorial.html

如果你有能力閱讀原文，那我很建議你去讀原本，再來看這篇筆記，因為這篇筆記會稍微加油添醋，會跟原本的教學有差異。

## 🗂 目錄

[TOC]

## 🎒 行前參考資料

* 🌐 官網 ：
    * uxn XXIIVV 官網：https://wiki.xxiivv.com/site/uxn.html
    * uxntal - uxn的程式語言（與基本介紹） (XXIIVV)：https://wiki.xxiivv.com/site/uxntal.html
* ⬇️ Runtime 和 下載  ：
    * 100r.co官網 https://100r.co/site/uxn.html
    * 網頁瀏覽器 Rumtime（by metasync）：https://metasyn.github.io/learn-uxn/
* 📖 參考：
    * uxntal 參考文件 (XXIIVV)：https://wiki.xxiivv.com/site/uxntal_reference.html
    * uxntal 作弊表 (XXIIVV)：https://wiki.xxiivv.com/site/uxntal_cheatsheet.html
    * varvara 參考文件 (XXIIVV)：https://wiki.xxiivv.com/site/varvara.html
* 🏛 論壇：
    * uxn 官方論壇：https://llllllll.co/t/uxn-virtual-computer/46103
* 📕 教學：
    * uxn官方支持教學：https://compudanzas.net/uxn_tutorial.html

> 💡 小小的建議：因為內容複雜度比較高，我的作法是會把大部分的參考資料印下來，之後有利於快速的翻閱。

## 1. Hello world

> 參考教學：https://compudanzas.net/uxn_tutorial_day_1.html

### 第一個程式 - Hello A

file: `hello.tal`
```
|0100

LIT 41
LIT 18 
DEO
```

### 組譯並執行

執行 `uxnasm` 來組譯我們的uxntal程式，接著使用uxn模擬器 `uxnemu` 來執行我們組譯好的 rom:

```shell 
$ uxnasm hello.tal -o hello.rom ; uxnemu hello.rom
```

如果不意外的話，你應該會看到一下畫面：

```
[一個全黑的視窗會彈出]

Assembled hello.rom in 5 bytes(0.01% used), 0 labels, 0 macros.
Loaded hello.rom
A
```

然後按下 `Ctrl+C` 停止目前執行的程式，因為目前程式不會終止。

### 解釋

先讓我們仔細看看程式中發生了什麼事情：

1. `|0100`：`0100` 是 Program Counter 的起始數值：`0x0100`。這意味著從這裡往後的所有程式都會被放在RAM（主記憶體）中的`0x0100`位置以後。 這個符號我們稱之為 {[`Absolute pad rune`](https://hackmd.io/@ljcucc/uxn#Absolute-pad-rune)}（之後會提到詳細運作原理）。
2. `LIT`: 當程式讀到 `LIT` 後，將會把下一個讀到的值 `push` 到 Working stack 中。
3. `41`: 當`41` 在ASCII code中代表著16進位的字母 `A`，而因為上一個是指令 `LIT`，所以 `41` 會被 `push` 到 Working stack。
4. `LIT`: 又讀到一次
5. `18`: `18`會被 push 到 Working stack 中。
6. `DEO`: 當遇到DEO指令時，DEO會從Working stack取（Pop）最後兩個數值，當作DEO的參數。
    * 第一個參數是：Device ID
    * 第二個參數是：要傳遞的 Value
    * 也就是說目前 uxn machine會對裝置 0x18 輸出數值41
    * 對於 uxn machine 來說 0x18 是 Console 輸出裝置，或者是Standard Output(device)（相對於C的fputc對STDIN）

一下是當執行完當前指令後，每一個Working Stack的狀態

| 當前指令 | 0x00 | 0x01 | 0x02 |
| -------- | -------- | -------- | -------- |
| 1 :`\|0100`    |
| 2 :`LIT`    | 
| 3 :`41`     | ***0x41***     |
| 4 :`LIT`    | ***0x41***     | 
| 5 :`18`    | ***0x41***     | ***0x18***     | 
| 6 :`DEO`    |

### Hello ABC with Literal rune

對於剛剛的hello A，我們可以寫出這個簡寫：

```
|0100

#41 #18 DEO
```

`#41` 是 `LIT 41`的一個簡寫，對於 `#41 #18` 我們也可以簡寫成 `#4118`（至於有什麼不同呢，我們等等會提到）

以此類推，我們可以用這個方式寫出 hello ABC:

```
|0100
#4118 DEO
#4218 DEO
#4318 DEO
```

output:
```
ABC[END]
```

### Hello world with raw character rune

對於char，uxntal有一個raw character rune，可以讓我們直接讓uxnasm幫我們轉換成ASCII hex的value（注意喔，是value不是literal）：

```
|0100
LIT 'A #18 DEO
LIT 'B #18 DEO
LIT 'C #18 DEO
```

output:

```
ABC[END]
```

因此我們就可以寫出hello 「World」：

```
|0100
LIT 'H #18 DEO
LIT 'E #18 DEO
LIT 'L #18 DEO
LIT 'L #18 DEO
LIT 'O #18 DEO
#2018 DEO (whitespace)
LIT 'W #18 DEO
LIT 'O #18 DEO
LIT 'R #18 DEO
LIT 'L #18 DEO
LIT 'D #18 DEO
```

output:

```
HELLO WORLD[END]
```

### 用 label 增加可讀性

接下來讓我們 label 來增加我們程式的可讀性：

```
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1]

|0100
LIT 'H .Console/write DEO
LIT 'E .Console/write DEO
LIT 'L .Console/write DEO
LIT 'L .Console/write DEO
LIT 'O .Console/write DEO
```

中間發生了什麼事情呢？對於assembler來說一切都是合理的，讓我們來看看吧：

* 首先，我們可以看到`|10 @Console`，`@`是用來宣告 `Label` 的符號，他可以讓我們取代一個數字，什麼數字呢？就是當前我們跟程式說：「位於位置10的地方後要寫⋯⋯⋯⋯」
* 然後 `[` 會被忽略（ {[詳細資料](https://hackmd.io/@ljcucc/uxn#-amp-)} ）

---

Contributed by: 

![](https://i.creativecommons.org/l/by-nc/3.0/tw/88x31.png)