Skip to content

Commit d6fbb58

Browse files
committed
Add brief symbol->label documentation
1 parent 0204e39 commit d6fbb58

File tree

1 file changed

+57
-49
lines changed

1 file changed

+57
-49
lines changed

www/notes/a86.scrbl

Lines changed: 57 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
@(require (for-label (except-in racket compile)
44
a86))
5-
5+
66
@(require scribble/examples
7-
redex/reduction-semantics
7+
redex/reduction-semantics
88
redex/pict
99
(only-in pict scale)
1010
(only-in racket system)
@@ -67,7 +67,7 @@ int gcd(int n1, int n2) {
6767
}
6868
HERE
6969
)
70-
70+
7171
(parameterize ([current-directory (build-path notes "a86")])
7272
(save-file "tri.s" (asm-string (tri 36)))
7373
(save-file "main.c" main.c)
@@ -178,7 +178,7 @@ Suppose we start executing at @tt{entry}.
178178
rbx} to zero. Executing this instruction sets a flag in the
179179
CPU, which affects subsequent ``conditional'' instructions.
180180
In this program, the next instruction is a conditional jump.}
181-
181+
182182
@item{@tt{je done} either jumps to the instruction
183183
following label @tt{done} or proceeds to the next
184184
instruction, based on the state of the comparison flag. The
@@ -192,7 +192,7 @@ Suppose we start executing at @tt{entry}.
192192
(register @tt{rsp}).}
193193

194194
@item{@tt{sub rbx, 1} decrements @tt{rbx} by 1.}
195-
195+
196196
@item{@tt{call tri} performs something like a function
197197
call; it uses memory as a stack to save the current location
198198
in the code (which is where control should return to after
@@ -222,7 +222,7 @@ Suppose we start executing at @tt{entry}.
222222
``output'') is 0.}
223223

224224
@item{@tt{ret} does a ``return,'' either to a prior call to
225-
@tt{tri} or the caller of @tt{entry}.}
225+
@tt{tri} or the caller of @tt{entry}.}
226226
]
227227

228228
Despite the lower-level mechanisms, this code computes in a
@@ -535,7 +535,7 @@ save the result of @racket['f]:
535535
(ex
536536
(eg (seq (Call 'f)
537537
(Mov 'rbx 'rax)
538-
(Call 'g)
538+
(Call 'g)
539539
(Add 'rax 'rbx)))
540540
)
541541

@@ -634,13 +634,13 @@ address to jump to, we could've also written it as:
634634
(ex
635635
(eg (seq (Sub 'rsp 8) ; allocate a frame on the stack
636636
; load address of 'fret label into top of stack
637-
(Lea (Offset 'rsp 0) 'fret)
637+
(Lea (Offset 'rsp 0) 'fret)
638638
(Jmp 'f) ; jump to 'f
639639
(Label 'fret) ; <-- return point for "call" to 'f
640640
(Push 'rax) ; save result (like before)
641641
(Sub 'rsp 8) ; allocate a frame on the stack
642642
; load address of 'gret label into top of stack
643-
(Lea (Offset 'rsp 0) 'gret)
643+
(Lea (Offset 'rsp 0) 'gret)
644644
(Jmp 'g) ; jump to 'g
645645
(Label 'gret) ; <-- return point for "call" to 'g
646646
(Pop 'rbx) ; pop saved result from calling 'f
@@ -706,7 +706,7 @@ Each register plays the same role as in x86, so for example
706706
@tt{?}. The only characters which may be used as the first character of an
707707
identifier are letters, @tt{.} (with special meaning), @tt{_}
708708
and @tt{?}."
709-
709+
710710
@ex[
711711
(label? 'foo)
712712
(label? "foo")
@@ -796,6 +796,17 @@ Each register plays the same role as in x86, so for example
796796
]
797797
}
798798

799+
@defproc[(symbol->label [s symbol?]) label?]{
800+
801+
Returns a modified form of a symbol that follows NASM label conventions.
802+
803+
@ex[
804+
(let ([l (symbol->label 'my-great-label)])
805+
(seq (Label l)
806+
(Jmp l)))
807+
]
808+
}
809+
799810
@deftogether[(@defstruct*[% ([s string?])]
800811
@defstruct*[%% ([s string?])]
801812
@defstruct*[%%% ([s string?])])]{
@@ -820,7 +831,7 @@ Each register plays the same role as in x86, so for example
820831
(%% "we're done!")
821832
(Ret))))
822833
}
823-
834+
824835
@defstruct*[Offset ([r register?] [i exact-integer?])]{
825836

826837
Creates an memory offset from a register. Offsets are used
@@ -865,7 +876,7 @@ Each register plays the same role as in x86, so for example
865876
@defstruct*[Extern ([x label?])]{
866877

867878
Declares an external label.
868-
879+
869880
}
870881

871882
@defstruct*[Global ([x label?])]{
@@ -909,7 +920,7 @@ Each register plays the same role as in x86, so for example
909920
}
910921

911922
@defstruct*[Mov ([dst (or/c register? offset?)] [src (or/c register? offset? 64-bit-integer?)])]{
912-
923+
913924
A move instruction. Moves @racket[src] to @racket[dst].
914925

915926
Either @racket[dst] or @racket[src] may be offsets, but not both.
@@ -918,7 +929,7 @@ Each register plays the same role as in x86, so for example
918929
(asm-interp
919930
(prog
920931
(Global 'entry)
921-
(Label 'entry)
932+
(Label 'entry)
922933
(Mov 'rbx 42)
923934
(Mov 'rax 'rbx)
924935
(Ret)))
@@ -931,12 +942,12 @@ Each register plays the same role as in x86, so for example
931942

932943
An addition instruction. Adds @racket[src] to @racket[dst]
933944
and writes the result to @racket[dst].
934-
945+
935946
@ex[
936947
(asm-interp
937948
(prog
938949
(Global 'entry)
939-
(Label 'entry)
950+
(Label 'entry)
940951
(Mov 'rax 32)
941952
(Add 'rax 10)
942953
(Ret)))
@@ -952,14 +963,14 @@ Each register plays the same role as in x86, so for example
952963
(asm-interp
953964
(prog
954965
(Global 'entry)
955-
(Label 'entry)
966+
(Label 'entry)
956967
(Mov 'rax 32)
957968
(Sub 'rax 10)
958969
(Ret)))
959970
]
960971
}
961972

962-
@defstruct*[Cmp ([a1 (or/c register? offset?)] [a2 (or/c register? offset? 32-bit-integer?)])]{
973+
@defstruct*[Cmp ([a1 (or/c register? offset?)] [a2 (or/c register? offset? 32-bit-integer?)])]{
963974
Compare @racket[a1] to @racket[a2]. Doing a comparison
964975
sets the status flags that affect the conditional instructions like @racket[Je], @racket[Jl], etc.
965976

@@ -972,14 +983,14 @@ Each register plays the same role as in x86, so for example
972983
(Cmp 'rax 2)
973984
(Jg 'l1)
974985
(Mov 'rax 0)
975-
(Label 'l1)
986+
(Label 'l1)
976987
(Ret)))
977-
]
988+
]
978989
}
979990

980991
@defstruct*[Jmp ([x (or/c label? register?)])]{
981992
Jump to label @racket[x].
982-
993+
983994
@ex[
984995
(asm-interp
985996
(prog
@@ -996,15 +1007,15 @@ Each register plays the same role as in x86, so for example
9961007
(Global 'entry)
9971008
(Label 'entry)
9981009
(Mov 'rax 42)
999-
(Pop 'rbx)
1010+
(Pop 'rbx)
10001011
(Jmp 'rbx)))
10011012
]
1002-
1013+
10031014
}
10041015

10051016
@defstruct*[Je ([x (or/c label? register?)])]{
10061017
Jump to label @racket[x] if the conditional flag is set to ``equal.''
1007-
1018+
10081019
@ex[
10091020
(asm-interp
10101021
(prog
@@ -1014,14 +1025,14 @@ Each register plays the same role as in x86, so for example
10141025
(Cmp 'rax 2)
10151026
(Je 'l1)
10161027
(Mov 'rax 0)
1017-
(Label 'l1)
1028+
(Label 'l1)
10181029
(Ret)))
10191030
]
10201031
}
10211032

10221033
@defstruct*[Jne ([x (or/c label? register?)])]{
10231034
Jump to label @racket[x] if the conditional flag is set to ``not equal.''
1024-
1035+
10251036
@ex[
10261037
(asm-interp
10271038
(prog
@@ -1031,14 +1042,14 @@ Each register plays the same role as in x86, so for example
10311042
(Cmp 'rax 2)
10321043
(Jne 'l1)
10331044
(Mov 'rax 0)
1034-
(Label 'l1)
1045+
(Label 'l1)
10351046
(Ret)))
10361047
]
10371048
}
10381049

10391050
@defstruct*[Jl ([x (or/c label? register?)])]{
10401051
Jump to label @racket[x] if the conditional flag is set to ``less than.''
1041-
1052+
10421053
@ex[
10431054
(asm-interp
10441055
(prog
@@ -1048,14 +1059,14 @@ Each register plays the same role as in x86, so for example
10481059
(Cmp 'rax 2)
10491060
(Jl 'l1)
10501061
(Mov 'rax 0)
1051-
(Label 'l1)
1062+
(Label 'l1)
10521063
(Ret)))
10531064
]
10541065
}
10551066

10561067
@defstruct*[Jle ([x (or/c label? register?)])]{
10571068
Jump to label @racket[x] if the conditional flag is set to ``less than or equal.''
1058-
1069+
10591070
@ex[
10601071
(asm-interp
10611072
(prog
@@ -1065,14 +1076,14 @@ Each register plays the same role as in x86, so for example
10651076
(Cmp 'rax 42)
10661077
(Jle 'l1)
10671078
(Mov 'rax 0)
1068-
(Label 'l1)
1079+
(Label 'l1)
10691080
(Ret)))
10701081
]
10711082
}
10721083

10731084
@defstruct*[Jg ([x (or/c label? register?)])]{
10741085
Jump to label @racket[x] if the conditional flag is set to ``greater than.''
1075-
1086+
10761087
@ex[
10771088
(asm-interp
10781089
(prog
@@ -1082,14 +1093,14 @@ Each register plays the same role as in x86, so for example
10821093
(Cmp 'rax 2)
10831094
(Jg 'l1)
10841095
(Mov 'rax 0)
1085-
(Label 'l1)
1096+
(Label 'l1)
10861097
(Ret)))
10871098
]
10881099
}
10891100

10901101
@defstruct*[Jge ([x (or/c label? register?)])]{
10911102
Jump to label @racket[x] if the conditional flag is set to ``greater than or equal.''
1092-
1103+
10931104
@ex[
10941105
(asm-interp
10951106
(prog
@@ -1099,7 +1110,7 @@ Each register plays the same role as in x86, so for example
10991110
(Cmp 'rax 42)
11001111
(Jg 'l1)
11011112
(Mov 'rax 0)
1102-
(Label 'l1)
1113+
(Label 'l1)
11031114
(Ret)))
11041115
]
11051116
}
@@ -1523,13 +1534,13 @@ Each register plays the same role as in x86, so for example
15231534

15241535
Decrements the stack pointer and then stores the source
15251536
operand on the top of the stack.
1526-
1537+
15271538
@ex[
15281539
(asm-interp
15291540
(prog
15301541
(Global 'entry)
15311542
(Label 'entry)
1532-
(Mov 'rax 42)
1543+
(Mov 'rax 42)
15331544
(Push 'rax)
15341545
(Mov 'rax 0)
15351546
(Pop 'rax)
@@ -1539,13 +1550,13 @@ Each register plays the same role as in x86, so for example
15391550

15401551
@defstruct*[Pop ([a1 register?])]{
15411552
Loads the value from the top of the stack to the destination operand and then increments the stack pointer.
1542-
1553+
15431554
@ex[
15441555
(asm-interp
15451556
(prog
15461557
(Global 'entry)
15471558
(Label 'entry)
1548-
(Mov 'rax 42)
1559+
(Mov 'rax 42)
15491560
(Push 'rax)
15501561
(Mov 'rax 0)
15511562
(Pop 'rax)
@@ -1569,7 +1580,7 @@ Perform bitwise not operation (each 1 is set to 0, and each 0 is set to 1) on th
15691580

15701581
@defstruct*[Lea ([dst (or/c register? offset?)] [x label?])]{
15711582
Loads the address of the given label into @racket[dst].
1572-
1583+
15731584
@ex[
15741585
(asm-interp
15751586
(prog
@@ -1614,20 +1625,20 @@ Perform bitwise not operation (each 1 is set to 0, and each 0 is set to 1) on th
16141625
(Mov 'rax 42)
16151626
(Ret)))
16161627
]
1617-
1628+
16181629
}
16191630

16201631
@defproc[(asm-string [is (listof instruction?)]) string?]{
16211632

1622-
Converts an a86 program to a string in nasm syntax.
1633+
Converts an a86 program to a string in nasm syntax.
16231634

16241635
@ex[
16251636
(asm-string (prog (Global 'entry)
16261637
(Label 'entry)
16271638
(Mov 'rax 42)
16281639
(Ret)))
16291640
]
1630-
1641+
16311642
}
16321643

16331644
@section{An Interpreter for a86}
@@ -1685,7 +1696,7 @@ The simplest form of interpreting an a86 program is to use
16851696
(Mov 'rax 0)
16861697
(Jmp 'rax))))
16871698
]
1688-
1699+
16891700
}
16901701

16911702
It is often the case that we want our assembly programs to
@@ -1732,7 +1743,7 @@ code:
17321743
(Sub 'rsp 8)
17331744
(Call 'gcd)
17341745
(Add 'rsp 8)
1735-
(Ret))))]
1746+
(Ret))))]
17361747

17371748
This will be particularly relevant for writing a compiler
17381749
where emitted code will make use of functionality defined in
@@ -1758,8 +1769,5 @@ linking error saying a symbol is undefined:
17581769

17591770
Like @racket[asm-interp], but uses @racket[in] for input and produce the result along
17601771
with any output as a string.
1761-
1762-
}
1763-
1764-
17651772

1773+
}

0 commit comments

Comments
 (0)