ESA S/390(X) Basics

TODO: Explain more in-depth

Definitions

There are some key rules that have to be taken in account when coding for the 390, in short:

The name of sizes are different than in x86:

Assembler syntax

Writing assembly code is like putting bricks together, you can "construct" instructions like brasl, br, b, etc. It allows you to place "constructs" after the instruction, for example "R" "qualifier" tells the instruction to operate on registers, "HI" tells the instruction to operate on a halfword immediate, "I" tells the instruction to operate on a inmmediate, and so on.

GAS allows you to specify registers in any way you want:

# Pseudo-AT&T syntax
larl %r14, myData

# NASM-like
larl r14, myData

# Only number
larl 14, myData

"Insert" means to place a value on the given register, some common instructions are:

Name Operands Full name Description
BRASL [register], [address]

Branch And Save Link

Will save the current PC (after BRASL) in register, then branch into the specified address

BR [register]

Branch Register

Will jump to the address contained in the register

IPM [register]

Insert Program Mask

Will load the program mask into the given register, you can shift by 28 bits to obtain the CC flag

SRL [register], [immediate]

Shift Right Link

Will shift register to the right by the amount specified by the immediate

SLL [register], [immediate]

Shift Left Link

Same as above, but with the left side instead

LARL [register], [address]

Load Address into Register Link

Will load the specified address into the specified register

LHI [register], [half-word immediate]

Loads a Half-word Immediate

Loads the immediate into the specified register

AHI [register], [half-word immediate]

Add a Half-word Immediate

Adds the immediate into the specified register

SHI [register], [half-word immediate]

Subtract a Half-word Immediate

Subtract the immediate from the specified register

OHI [register], [half-word immediate]

ORs a Half-word Immediate

ORs the immediate into the specified register

NHI [register], [half-word immediate]

ANDs a Half-word Immediate

ANDs the immediate into the specified register

C [register], [register]

Compare

Compares a register with another register

BNE [address]

Branch if Not Equal

BNZ [address]

Branch if Not Zero

BZ [address]

Branch if Zero

BE [address]

Branch if Equal

High Level Assembler

Normally in S390 the assembly is done via HLASM, however most people prefer to use tools such as GAS. But sometimes you need to translate HLASM code to GAS

This is just a short description

Data Constant

Data Constant (abbreviated as DC) defines a constant which will be put in the final binary

* Insert a halfword
        DC X'00FF'

* Insert a character
        DC X'0F'

Data S

Data S does not insert a constant into the final binary, however it is commonly used for alignment purpouses

* Pads to the half word boundary
        DS 0H

* 2 uninitialized characters
        DS CL2

DS stands for Define Storage while DC stands for Define Character

Macros

HLASM uses macros too often, you'll see definitions like FLCIOA or FLCNPSW and such around HLASM code, those are part of macro libraries. However here is a small set of them defined in GAS syntax:

.equ AMBIT,    0x80000000
.equ FLCCAW,   0x48
.equ FLCSNPSW, 0x60
.equ FLCPNPSW, 0x68
.equ FLCINPSW, 0x78
.equ FLCMNPSW, 0x70
.equ FLCIOA,   0xB8

Operation modes and states

There are 2 states that may be useful to know, the problem state and the supervisor state. The problem state does not allow unprivileged execution of applications - this resembles usermode and can be used to "jail" rogue kernel modules. The supervisor state has full control over the machine and is usually where your kernel will run.

"Gotchas"

The stack is in reverse

On x86 architectures the top of the stack is used as the initial RSP value, in S390 you use the bottom part of the stack instead.