diff options
| author | Sebastian G. Kirmayer <gloria@gloria-mundi.eu> | 2026-07-07 23:54:15 +0200 |
|---|---|---|
| committer | Sebastian G. Kirmayer <gloria@gloria-mundi.eu> | 2026-07-07 23:54:15 +0200 |
| commit | 9a6c7d85eb1be819b94d0feb0cb84de8546e36fd (patch) | |
| tree | 73bab5bccdeffed245bd596cdeadde5cfddeb42f /HACKING | |
Diffstat (limited to 'HACKING')
| -rw-r--r-- | HACKING | 83 |
1 files changed, 83 insertions, 0 deletions
@@ -0,0 +1,83 @@ +asm.sh +====== + +asm.sh is an assembler embedded into POSIX shell. It defines functions for +all (supported) i386 instructions. + +It generally follows AT&T syntax, modified in many places to avoid characters +reserved by the shell. Arguments are separated by spaces, no comma allowed +(as usual in shell). Width suffixes are generally mandatory. + +Labels +------ + +There are two kinds of label: Global and local labels. + +Global labels are defined with the `label' function, e.g.: + +label _start + +They must be globally unique. Global labels are referred to by their name, +e.g. `_start'. + +They can also be relative; the following defines a label `offset' whose value +is the difference between the current location and the value of the label +`base': + +label offset base + +Local labels are defined with the `L' function, e.g.: + +L loop + +There can be several definitions of a local label. There are two ways to +refer to a local label: + +- `loop^' refers to the previous declaration of the label +- `loop.' refers to the next declaration of the label + +Operands +-------- + +Immediates: Either a label, or an integer literal in decimal, octal +(preceded by 0) or hexadecimal (preceded by 0x). + +Registers: Preceded by `%' as in AT&T, e.g. `%eax'. + +Memory operands: Start with `@', followed by a sum expression. Examples: + + AT&T | asm.sh + -------------------|------------------- + 0x100 | @0x100 + label | @label + 4(%eax) | @%eax+4 + 4(,%eax) | @1%eax+4 + 14(,%eax,2) | @14+2%eax + (%eax,%ebx) | @%eax+%ebx + (%ebx,%eax) | @%ebx+%eax + (%ebx,%eax) | @1%eax+%ebx + 12(%ebx,%eax,8) | @%ebx+8%eax+12 + + The order of the summands is generally irrelevant, except that if there are + two unscaled registers, the first is taken to be the base and the second + the index. Displacement can be a label, scale must be one of the literal + characters 1, 2, 4, or 8 (or omitted, implicitly 1). + +Calling convention +================== + +The first three arguments are passed in %eax, %ecx and %edx. Remaining +arguments are passed on the stack in right-to-left order (last argument is +pushed first), and cleaned up by the callee. + +The return value currently always fits in three registers; it is placed in +%eax, %ecx, and %edx. Some functions also modify EFLAGS, e.g. streq sets +ZF iff the strings are equal. + +Functions may clobber %eax, %ecx and %edx. Stack must be 4-byte aligned. + +Porting +======= + +To port to other operating systems, it should be sufficient to modify asm.sh +(for the ELF header) and start.asm (for system calls etc). |
