8 ms·
To understand assembly it really helps to know at least something about how computers work on a low level. When I first tried learning it (long time ago, in a h
by ivanhoe 10y ago
To understand assembly it really helps to know at least something about how computers work on a low level. When I first tried learning it (long time ago, in a high school) I had no idea how computers really work on such a low level, how CPU's addressing registers and that kind of stuff, and while I managed to learn the syntax, even write some asm code, it was all really confusing to me. And only few years later on University, after I've learned in details about the cpu architecture, registers, buses, DMA, etc, it suddenly all started to make perfect sense and became 100x more clear and easier. So if you're interested in this, it will save you a lot of effort to invest some time first to learn the computer architecture basics, and then from there go to learn the assembly lang. Just my $0.02
- theparanoid 10y agoIt's helpful to realize x86 assembly is not what's executed by the machine; machine code is. One assembly instruction, e.g. ADDL, is translated to several different machine code instructions depending on the destination, source, and addressing mode.
- amw-zero 10y agoCan you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one machine instruction.
- anarazel 10y agoI suspect the instructions they are thinking about are cpu-level uops.
- spc476 10y agoI'm looking at the Microsoft Macro Assembler 5.1 Reference manual (it was nearby and easily accessible to me; yes it's old (from the very late 80s or early 90s) but it covers the 32 bit 80386, which is still valid. Anyway, it shows three different encodings for the ADD instruction. The first: 000000dw mod,reg,r/m This adds register to register, or memory to register (either direction, the d above) using either 8 or 16/32 bits (the w above [1]). The second form: 100000sw mod,000,r/m This adds an immediate value (8 or 16 bits, w again) to a register. The s bit is used to sign extend the data (s=1; otherwise, 0-extend it) if required [2]. The final form: 0000010w data This adds an immediate value to the accumulator register (EAX, AX, AL) [1]. That's three different encodings for the "same" instruction. The MOV instruction (and again, I'm only talking about the 80386 here) has 8 different encodings, depending upon registers used. [1] If the current code segment is designated as a 16-bit segment, then the w means 16 bits, unless a size override byte (an opcode prefix byte) is present, in which case it means 32-bits. If the current code segment is designated as a 32-bit segment, then the w means 32 bits, again unless a size override byte is present, in which case it means 16-bits. [2] It seems to me that if w=1, then the s bit is extraneous and thus could be used to encode other instructions. I'm not sure if that is the case but it's common to use otherwise nonsensical instruction encoding to do something useful.
- userbinator 10y agoIt seems to me that if w=1, then the s bit is extraneous and thus could be used to encode other instructions. I'm not sure if that is the case but it's common to use otherwise nonsensical instruction encoding to do something useful. Opcode 82h is an alias for 80h --- it presumably sign-extends the immediate value into an internal temporary register, but the upper bits don't matter anyway since it's an 8-bit add. Some interesting discussion on that here, along with an example application: http://computer-programming-forum.com/46-asm/143edbd28ae1a091.htm http://computer-programming-forum.com/46-asm/143edbd28ae1a09...
- jussij 10y agoHere are the opcodes for the x86 ADD assembler instruction: http://www.mathemainzel.info/files/x86asmref.html#add http://www.mathemainzel.info/files/x86asmref.html#add The link shows nine ways to use the ADD instruction with each method resulting in a different opcode.
- amw-zero 10y agoThere's a bit of a miscommunication going on. What I meant was, when you write an assembly instruction, that maps to one machine instruction. I.e., because of things like addressing modes, different invocations of an ADD instruction can map to different machine instructions. But one ADD invocation will always map to one machine instruction. The parent comment sounded to me like one assembly instruction could map to several machine instructions, like one line of C is equivalent to several lines of assembly. Just wanted to clarify that that isn't the case.
- Narishma 10y agoI read it as one assembly instruction can map to one of several machine instructions.
- userbinator 10y agoThat is also true --- for example, "mov reg, reg" is a special case of "mov reg, r/m" or "mov r/m, reg" with the r/m specifying a register, so basically two separate sequences of bytes which perform the same operation. This has been exploited by copy-protection and steganography, going back to the A86 shareware assembler which was the first use of this technique that I can remember, to more recent developments: https://www.cs.columbia.edu/~angelos/Papers/hydan.pdf https://www.cs.columbia.edu/~angelos/Papers/hydan.pdf http://stackoverflow.com/questions/17973103/why-does-the-solaris-assembler-generate-different-machine-code-than-the-gnu-asse http://stackoverflow.com/questions/17973103/why-does-the-sol... (Almost wish that last link was cut off one letter earlier...)
- wolfgke 10y ago> There's a bit of a miscommunication going on. What I meant was, when you write an assembly instruction, that maps to one machine instruction. That's not true on x86-16, x86-32 and x86-64. For example 060o, 310o and 062o, 301o (...o means "octal"; for the reason why I give this example in octal instead of hexadecimal cf. https://news.ycombinator.com/item?id=13051770 https://news.ycombinator.com/item?id=13051770) both stand for "xor al, cl" (the assembler you use will one of the two encodings) - for those people who really prefer hexadecimal here: It corresponds to 30h, C8h and 32h, C1h The fact that there are different ways to encode some instructions was used by the A86 assembler (https://en.wikipedia.org/w/index.php?title=A86_(software)&oldid=738208372 https://en.wikipedia.org/w/index.php?title=A86_(software)&ol...) to watermark machine code that was generated by it; in particular to detect whether it was generated by a registered or unregistered version of A86: "The assembler automatically embeds a "fingerprint" into the generated code through a particular choice of functionally equivalent instruction encodings. This makes it possible to tell if code was assembled with A86, and also to distinguish between registered and unregistered versions of the assembler, although access to the source code is required."
- erubin 10y agohttp://www.cs.princeton.edu/courses/archive/spr16/cos217/lectures/16_MachineLang.pdf http://www.cs.princeton.edu/courses/archive/spr16/cos217/lec...
- vram22 10y ago>Can you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one machine instruction. Seeing the confusion and clarifications in the replies to your comment, I think it may have been more clear if you had said (and you probably meant): "Can you point to a source for this? All x86 assemblers that I know of map one assembly instruction to one out of a set of machine instructions (where the chosen machine instruction depends on things like the addressing mode (immediate, indexed, indirect indexed, etc. - I'm using older terms for addressing mode, not sure if they are valid now with newer processors. but the concept is the same).
- khuey 10y agoThere would be much less confusion about this in the descendant posts if this said "One assembly mnemonic is translated to ..."
- adamnemecek 10y agoYeah stuff like dma isn't getting enough attention in a lot of treatments of the subjects. Also in/out instructions (did you ever consider how a CPU talks to a HDD)?
- spc476 10y agoTwo ways. The first is IO mapped IO, which is what the x86 supports with the IN and OUT instructions. All this really is is a MOV to a different "address" space (16 bits of addressing). The second is memory mapped IO, in which hardware is mapped to the addressing space of the CPU (Motorola 68K uses this format). A CPU that allows IO mapped IO can also do memory mapped IO (it's not precluded).
- andars 10y agoQuestion I've been wondering about for a while: where does PCI fall into this? Do modern x86 PC systems still use in & out at all?
- detaro 10y agoPCI did for discovery, and could use it for device access (but often also memory-mapped). More info from the osdev wiki, which btw is a great place if you want to know about low-level initialization, the boot process etc. http://wiki.osdev.org/PCI http://wiki.osdev.org/PCI
- en4bz 10y agoI found this article to be helpful on how PCIe interacts with the CPU: http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1 http://xillybus.com/tutorials/pci-express-tlp-pcie-primer-tu...
- Ericson2314 10y agoDon't forget DMA is different from both of those too.
- userbinator 10y agoI always recommend this book for those who would like to know how computers really work: https://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0735611319 https://www.amazon.com/Code-Language-Computer-Hardware-Softw...
- RandomOpinion 10y agoWhile I like Petzold's "Code", it's really aimed at nontechnical audiences. Jon Stokes' "Inside the Machine" or Nisan and Schocken's textbook "The Elements of Computing Systems" are far better if you have a technical background.
- grzm 10y agoI second the Stokes recommendation. I have very little hardware background, but quite a bit science and tech (engineering). He provided the right amount of background and introduction for me.