FAQ
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

--

Search Discussions

  • Dave Cheney at Jan 24, 2013 at 12:13 am
    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

    On Thu, Jan 24, 2013 at 11:06 AM, Dan Kortschak
    wrote:
    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

    --
    --
  • Donovan Hide at Jan 24, 2013 at 12:44 am
    I learnt a lot from the replies on this thread:

    https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/j7GTMNQQxRU

    Nigel's post is particularly worth referring to.

    Cheers,
    Donovan.

    --
  • Dan Kortschak at Jan 24, 2013 at 5:03 am
    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

    On Thu, 2013-01-24 at 11:13 +1100, Dave Cheney wrote:
    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.

    --
  • Ron minnich at Jan 24, 2013 at 5:08 am

    On Thu, Jan 24, 2013 at 12:03 AM, Dan Kortschak 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 at Jan 24, 2013 at 5:21 am
    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
    On Thu, 2013-01-24 at 00:08 -0500, ron minnich wrote:
    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.

    --
  • Dave Cheney at Jan 24, 2013 at 5:54 am
    It's character building.
    That's the spirit!

    --
  • Lucio at Jan 24, 2013 at 5:40 am
    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.

    --
  • Roberto Waltman at Jan 24, 2013 at 6:57 pm

    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 at Jan 24, 2013 at 7:06 pm

    On Fri, Jan 25, 2013 at 2:02 AM, Roberto Waltman 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 at Jan 24, 2013 at 7:42 pm

    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<javascript:>
    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 at Jan 24, 2013 at 7:59 pm

    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 at Jan 24, 2013 at 8:22 pm

    On 2013/1/24 Donovan Hide wrote:
    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 :-)
    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 at Jan 24, 2013 at 8:34 pm

    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.

    --
  • Dave Cheney at Jan 24, 2013 at 5:54 am

    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
    thanks
    Dan

    On Thu, 2013-01-24 at 11:13 +1100, Dave Cheney wrote:
    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.
    --
  • Dan Kortschak at Jan 24, 2013 at 6:12 am
    Ah... sneaky.
    On Thu, 2013-01-24 at 16:54 +1100, Dave Cheney wrote:
    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

    --
  • Ron minnich at Jan 24, 2013 at 6:45 am
    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

    --
  • Dan Kortschak at Jan 24, 2013 at 7:23 am
    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
    On 24/01/2013, at 5:15 PM, "ron minnich" wrote:

    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 at Jan 24, 2013 at 7:27 am

    On Thu, Jan 24, 2013 at 4:54 PM, Dave Cheney 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 at Jan 24, 2013 at 7:48 am
    Yes, I got that from the plan9 docs. I like that bit of design.
    On 24/01/2013, at 5:57 PM, "Nigel Tao" wrote:
    On Thu, Jan 24, 2013 at 4:54 PM, Dave Cheney 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.
    --
  • Nigel Tao at Jan 24, 2013 at 7:09 am

    On Thu, Jan 24, 2013 at 4:03 PM, Dan Kortschak 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 at Jan 24, 2013 at 7:25 am
    I was trying to figure out something like this. Thanks.

    Dan
    On 24/01/2013, at 5:39 PM, "Nigel Tao" wrote:

    On Thu, Jan 24, 2013 at 4:03 PM, Dan Kortschak
    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
    ...
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 24, '13 at 12:07a
activeJan 24, '13 at 8:34p
posts22
users10
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase