*a use and asm - good place to learn?

260 views
Skip to first unread message

Dan Kortschak

unread,
Jan 23, 2013, 7:06:58 PM1/23/13
to golan...@googlegroups.com
Hello,

I'm interested in learning a little about asm and the Plan9 assembler
and linker. I've read the manuals, but that reasonable expect a greater
level of knowledge than I have (the last time I wrote assembler was for
a Z80 embedded device about 25 years ago).

Where is a good place to start this journey?

thanks
Dan

Dave Cheney

unread,
Jan 23, 2013, 7:13:30 PM1/23/13
to Dan Kortschak, golan...@googlegroups.com
I can't speak for others but IMO the source is your best starting
place. I would read the .s files in the following order, bytes/,
syscall/, crypto/, math/, runtime/

The least obvious things are the calling convention and the magic
suffixes on the end of TEXT declarations.

Robert Sandra frequently posts about specific questions he has while
reading the source. I think this is useful as it creates a public
record of answers which are current to that point.

Cheers

Dave
> --
>
>

Donovan Hide

unread,
Jan 23, 2013, 7:44:40 PM1/23/13
to Dave Cheney, Dan Kortschak, golang-nuts
I learnt a lot from the replies on this thread:


Nigel's post is particularly worth referring to.

Cheers,
Donovan.

Dan Kortschak

unread,
Jan 24, 2013, 12:03:24 AM1/24/13
to Dave Cheney, golan...@googlegroups.com
OK. I think this is going to be a steep learning curve. Apologies ahead
of time.

I have three questions to start.

1. Is there a good place to look for translation between Plan9 asm
and Intel/GNU asm? I don't have enough asm in my head to be able
to imagine what many of the ops are doing.
2. Related to the first question, the N in REPN is nz or ne? (I'm
starting on snippets that are simple).
3. When an asm_arch.s defined function does not exist for a
specific function in a go function declaration the build falls
back to a pure go function. In bytes for IndexByte, this is
indexBytePortable. How is this specified?

thanks
Dan

ron minnich

unread,
Jan 24, 2013, 12:08:15 AM1/24/13
to Dan Kortschak, Dave Cheney, golan...@googlegroups.com
On Thu, Jan 24, 2013 at 12:03 AM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> OK. I think this is going to be a steep learning curve. Apologies ahead
> of time.
>
> I have three questions to start.
>
> 1. Is there a good place to look for translation between Plan9 asm
> and Intel/GNU asm? I don't have enough asm in my head to be able
> to imagine what many of the ops are doing.

I'm utterly lost on why you want to learn plan 9 asm. It's not really
meant for human consumption. In fact I always thought it had the
virtue of discouraging it.


As the man page says, assembly is the ultimate dead language.

ron

Dan Kortschak

unread,
Jan 24, 2013, 12:21:10 AM1/24/13
to ron minnich, Dave Cheney, golan...@googlegroups.com
It's character building.

Seriously... I'm interested in being able to read more of the source and
occasionally write functions for tight loops. The Go tool chain (as far
as I can see) uses plan9 asm, so this is what I need to learn if that's
what I want to do.

Dan

Lucio

unread,
Jan 24, 2013, 12:40:15 AM1/24/13
to golan...@googlegroups.com, Dan Kortschak, Dave Cheney
I'm going to take exception here! (a) Understanding computing without knowing
assembler doesn't seem possible, although you need not actually know each and
every possible instruction, you do need to know enough for the architecture to be
meaningful and (b) without a working knowledge of assembler there are tasks that
cannot be completed: porting Go to Plan9/arm is a case in point.

I cut my teeth on the Univac 1100 series assembler (in parallel with FORTRAN, to
 give you scope for additional sarcasm, Ron) and it gave me an advantage over my
class mates that I believe is still with me.  I find it sad that my understanding of the
Plan 9 assemblers is nowhere near in that league.

Which reminds me, does anyone here know where I can get a copy of that wonderful
textbook by Hollingdale and Toothill I seem to recall was entitled "Digital Computers"?

Lucio.

Dave Cheney

unread,
Jan 24, 2013, 12:54:30 AM1/24/13
to Dan Kortschak, golan...@googlegroups.com
> 1. Is there a good place to look for translation between Plan9 asm
> and Intel/GNU asm? I don't have enough asm in my head to be able
> to imagine what many of the ops are doing.

Sadly not, and you need to be bilingual when working with plan9 asm,
(go build -gcflags -S) and gas asm which is the default for objdump
and gdb. The most obvious example gas reads right to left, and plan9
is left to right. The other major change is the MOV instruction, which
is a generic reg -> mem, mem -> reg, and reg -> reg instruction which
is replaced the correct instruction at link(?) time. Sometimes this
can include use of a scratch register to construct one of the operands
if it is not possible to directly encode this. For 6a that shouldn't
be a problem, but is a gotcha in 5a.

> 2. Related to the first question, the N in REPN is nz or ne? (I'm
> starting on snippets that are simple).

Unknown, grep src/cmd/6a/lex.c shows

odessa:6a dfc$ grep AREPN *
lex.c: "REPN", LTYPE0, AREPN,

odessa:6l dfc$ grep AREPN *
6.out.h: AREPN,
optab.c: { AREPN, ynone, Px, 0xf2 },

Then you need to get the intel instruction manual out. Sometimes the
asm in the same file gives a hint, sometimes you have to dig. Luckily
arm only has a few bits for instruction encoding, so I've managed to
avoid learning this skill.

> 3. When an asm_arch.s defined function does not exist for a
> specific function in a go function declaration the build falls
> back to a pure go function. In bytes for IndexByte, this is
> indexBytePortable. How is this specified?

There is no fallback, for example in older version of bytes/arm_arm.s,
the IndexByte function is forward to IndexBytePortable like so.

https://code.google.com/p/go/source/browse/src/pkg/bytes/asm_arm.s?name=release-branch.r60

Cheers

Dave

Dave Cheney

unread,
Jan 24, 2013, 12:54:50 AM1/24/13
to Dan Kortschak, ron minnich, golan...@googlegroups.com
> It's character building.

That's the spirit!

Dan Kortschak

unread,
Jan 24, 2013, 1:12:41 AM1/24/13
to Dave Cheney, golan...@googlegroups.com
Ah... sneaky.

ron minnich

unread,
Jan 24, 2013, 1:44:56 AM1/24/13
to Dan Kortschak, Dave Cheney, golan...@googlegroups.com
Actually, I still do a lot of assembly -- it's my day job. But I would
not recommend someone new to assembly start with the plan 9 assembler.
I like it but it's not going to match a lot of what is documented out
there and it can get very confusing as many instructions are not
represented.

If you're serious about x86 assembly the highly rated tools are nasm
and gas, in that order, at least in my world. I mainly use gas.

No sarcasm intended. I just see a lot of people who want to jump into
assembly and I always end up wondering why.

Generally when I am trying to create plan 9 assembly I start with a
trivial C program and let 6c generate assembly, and then modify to
taste. There are one or two gotchas and it's simplest to let 6c take
care of getting these details right. I've used this approach for plan
9 and nix work on ARM, PPC, x86, and amd64 and it works pretty well --
I even used it to generate the cache invalidate loops for one of the
plan 9 arm ports.

ron

Nigel Tao

unread,
Jan 24, 2013, 2:09:36 AM1/24/13
to Dan Kortschak, Dave Cheney, golang-nuts
On Thu, Jan 24, 2013 at 4:03 PM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> 1. Is there a good place to look for translation between Plan9 asm
> and Intel/GNU asm? I don't have enough asm in my head to be able
> to imagine what many of the ops are doing.
> 2. Related to the first question, the N in REPN is nz or ne? (I'm
> starting on snippets that are simple).

One way to translate Plan9 asm (such as REPN) to Gas asm is to compile
with "go build" and disassemble with objdump. The foo asm function
below is nonsensical, but it should show the technique.

$ ls
foo_amd64.s main.go
$ cat foo_amd64.s
TEXT ·foo(SB),7,$0
REPN; SCASB
RET
$ cat main.go
package main

func foo()

func main() {
foo()
}
$ go build -o x . && objdump -d x | sed -n '/main.foo.:/,/^$/p'
0000000000400c60 <main.foo>:
400c60: f2 ae repnz scas %es:(%rdi),%al
400c62: c3 retq
...

Dan Kortschak

unread,
Jan 24, 2013, 2:23:52 AM1/24/13
to ron minnich, Dave Cheney, golan...@googlegroups.com
In all seriousness, this is not something I want to do for its own sake. I initially started to learn Go because what I needed was something that was reasonably fast and reasonably easy to learn; I was rewriting something written in C and my C was not good enough to do this in that language. Over time, I've found that sometimes I need extra speed and so as a happy consequence my C has been improving. It seems that for some tasks assembler would be more appropriate so I'm considering this option as well.

This is a very pragmatic path.

I like the idea of taking the output of a C compiler and either learning from it modifying it.

Dan

Dan Kortschak

unread,
Jan 24, 2013, 2:25:19 AM1/24/13
to Nigel Tao, Dave Cheney, golang-nuts
I was trying to figure out something like this. Thanks.

Dan

Nigel Tao

unread,
Jan 24, 2013, 2:27:27 AM1/24/13
to Dave Cheney, Dan Kortschak, golang-nuts
On Thu, Jan 24, 2013 at 4:54 PM, Dave Cheney <da...@cheney.net> wrote:
> The other major change is the MOV instruction, which
> is a generic reg -> mem, mem -> reg, and reg -> reg instruction which
> is replaced the correct instruction at link(?) time.

Yeah, the linker does it. On amd64, the relevant lines in src/cmd/6l/optab.c are

{ AMOVQ, ymovq, Pw, 0x89, 0x8b, 0x31, 0xc7,(00), 0xb8, 0xc7,(00),
0x6f, 0x7f, 0x6e, 0x7e, Pf2,0xd6, Pf3,0x7e, Pe,0xd6, Pe,0x6e, Pe,0x7e
},

and

uchar ymovq[] =
{
Yrl, Yml, Zr_m, 1, // 0x89
Yml, Yrl, Zm_r, 1, // 0x8b
Yi0, Yrl, Zclr, 1, // 0x31
// etc.
}

A MOVQ from register to memory is opcode 0x89. A MOVQ from memory to
register is opcode 0x8b. A MOVQ of an immediate 0 to register is
re-written as a xor (it's shorter), which is opcode 0x31. Et cetera.
See the comment starting with "You are doasm" for more details.

Dan Kortschak

unread,
Jan 24, 2013, 2:48:12 AM1/24/13
to Nigel Tao, Dave Cheney, golang-nuts
Yes, I got that from the plan9 docs. I like that bit of design.

Roberto Waltman

unread,
Jan 24, 2013, 1:02:13 PM1/24/13
to golan...@googlegroups.com
Lucio wrote:
> I'm going to take exception here! (a) Understanding computing without
> knowing
> assembler doesn't seem possible

True, but this is also true:

"Assembly programming is to reliable software as smoking is to health.
You are not serious about the latter until giving up the former."
(Andy Goldstein in one of the X-Plane lists. Quoting from memory, may be
slightly off ...)

> ... where I can get a copy of that wonderful
> textbook by Hollingdale and Toothill I seem to recall was entitled
> "Digital Computers"?

http://www.abebooks.co.uk/servlet/BookDetailsPL?bi=1028059408&searchurl=kn%3DElectronic-Computers-Hollingdale-H-Toothill%26sts%3Dt%26x%3D35%26y%3D12

--
Roberto Waltman

minux

unread,
Jan 24, 2013, 2:06:16 PM1/24/13
to Roberto Waltman, golan...@googlegroups.com
On Fri, Jan 25, 2013 at 2:02 AM, Roberto Waltman <ggr...@rwaltman.com> wrote:
Lucio wrote:
I'm going to take exception here! (a) Understanding computing without knowing
assembler doesn't seem possible

True, but this is also true:

"Assembly programming is to reliable software as smoking is to health.
You are not serious about the latter until giving up the former."
(Andy Goldstein in one of the X-Plane lists. Quoting from memory, may be slightly off ...)
This is off-topic.
But I also strongly believe that a firm understanding of assembly programming is a
necessary prerequisite of serious computer programming.

I don't mean we should program in assembly, only that you must know the underlying
details to be a better programmer; and I think Lucio also doesn't mean we should write
in assembly.

bryanturley

unread,
Jan 24, 2013, 2:42:40 PM1/24/13
to golan...@googlegroups.com, Roberto Waltman


On Thursday, January 24, 2013 1:06:16 PM UTC-6, minux wrote:

On Fri, Jan 25, 2013 at 2:02 AM, Roberto Waltman <ggr...@rwaltman.com> wrote:
Lucio wrote:
I'm going to take exception here! (a) Understanding computing without knowing
assembler doesn't seem possible

True, but this is also true:

"Assembly programming is to reliable software as smoking is to health.
You are not serious about the latter until giving up the former."
(Andy Goldstein in one of the X-Plane lists. Quoting from memory, may be slightly off ...)
This is off-topic.
But I also strongly believe that a firm understanding of assembly programming is a
necessary prerequisite of serious computer programming.

 
I would have to agree 100%.  I wish cs students would learn assembly earlier.

Donovan Hide

unread,
Jan 24, 2013, 2:59:07 PM1/24/13
to bryanturley, golang-nuts, Roberto Waltman

This is off-topic.
But I also strongly believe that a firm understanding of assembly programming is a
necessary prerequisite of serious computer programming.

 
I would have to agree 100%.  I wish cs students would learn assembly earlier.

Learning to read assembly also helps you understand how the compiler works which enables you to write non-assembly code which will run faster. Profiling will also usually centre on an assembly instruction. Working out which part of a line of code is causing the problem is another beneficial side effect of understanding assembly.

Also, it's fun :-)

   

Rémy Oudompheng

unread,
Jan 24, 2013, 3:15:36 PM1/24/13
to Donovan Hide, bryanturley, golang-nuts, Roberto Waltman
Assembly has been quite unhelpful for me in optimization and
profiling. The main things I look at in compiler assembly output are:
* memory allocations
* size of stack frames (thanks to Dmitry for making stacks cheaper)
* how many functions calls (interface conversions)

Apart from these observations, it is rather hard to evaluate the speed
of generated code from generated assembly. There are too many ways
code can be slowed down: badly-behaved memory accesses, concurrency,
suboptimal pipelining... Modern CPUs are too compilcated for human
beings to understand the correlation.

Rémy.

bryanturley

unread,
Jan 24, 2013, 3:33:58 PM1/24/13
to golan...@googlegroups.com


On Thursday, January 24, 2013 2:15:36 PM UTC-6, Rémy Oudompheng wrote:
 Modern CPUs are too compilcated for human
beings to understand the correlation.


It all makes sense now, cpus and compilers are of alien origin!
TAKE ME TO YOUR LEADER ;)

I wouldn't say it is to hard for us to understand,  I would say by the time we understand how to optimize for one sub-arch a new one is released.
Therefore it is not usually advantageous to write in assembly, unless you want access to things like sse that compilers don't generally handle well.
I would not advocate writing software completely in assembly, except when you are learning how to write software initially.

Reply all
Reply to author
Forward
0 new messages