# SWPB — Swap Byte

Source: https://rungs.dev/docs/structured-text/instructions/swpb

> SWPB in rungs.dev Structured Text writes an INT or DINT with its bytes in a new order, to read numbers and text from devices that store bytes the other way round.

A `DINT` is 4 bytes and an `INT` is 2. Not every device stores them in the same order. A drive,
a scale or a gateway that sends a number or text in Modbus registers often puts the bytes the
other way round, so a value that should be `16#1234` arrives as `16#3412`, and text arrives
with each pair of letters swapped: `'ABCRDO1E'` where the device sent `'BARCODE1'`. `SWPB`
puts the bytes back in order.

`SWPB` is a **statement of its own** that writes its last operand. It gives back no value, so
`Reading := SWPB(Raw, HIGHLOW);` is refused: write `SWPB(Raw, HIGHLOW, Reading);`.

```iecst
SWPB(Raw_Register, HIGHLOW, Reading);
```

## Operands [#operands]

| Name        | Type            | Notes                                      |
| ----------- | --------------- | ------------------------------------------ |
| `source`    | `DINT` \| `INT` | a tag, never a number typed in             |
| `orderMode` | a word          | `REVERSE`, `WORD` or `HIGHLOW`, or `0`–`2` |
| `dest`      | `DINT` \| `INT` | the same type as `source`, or a `DINT`     |

The order mode is a word written straight into the statement, never a tag. Structured Text
spells the third one `HIGHLOW`, with no slash; a ladder box spells it `HIGH/LOW`.

## What each order mode does [#what-each-order-mode-does]

Picture a `DINT` as four bytes `A B C D`, with `A` the highest:

| Order mode | Number | `A B C D` becomes | `16#12345678` becomes |
| ---------- | ------ | ----------------- | --------------------- |
| `REVERSE`  | `0`    | `D C B A`         | `16#78563412`         |
| `WORD`     | `1`    | `C D A B`         | `16#56781234`         |
| `HIGHLOW`  | `2`    | `B A D C`         | `16#34127856`         |

An `INT` has only two bytes, so every order mode does the same thing to it: swaps them.
`16#1234` becomes `16#3412`. An `INT` source may go into a `DINT` destination. The swapped
`INT` keeps its sign there, so `16#12AB` becomes `16#AB12`, which as an `INT` is `-21742`, and
the `DINT` holds `-21742`. A `DINT` source cannot go into an `INT`: half its bytes would have
nowhere to go.

## Example — swap every register in an array [#example--swap-every-register-in-an-array]

A device sends text two letters to an `INT`, high byte first. Swapping each `INT` in place puts
the letters in the order the controller reads them:

```iecst
FOR i := 0 TO 5 DO
    SWPB(Registers[i], HIGHLOW, Registers[i]);
END_FOR;
```

The source and the destination may be the same tag, as here.

## Common Mistakes [#common-mistakes]

- Writing `HIGH/LOW` in Structured Text. That is the ladder spelling; here it is `HIGHLOW`.
- Putting the order mode in a tag. It is a word typed into the statement.
- Choosing the wrong order mode. Compare the value you get with the one the device's manual
  shows: two letters swapped in each pair is `HIGHLOW`, two halves swapped is `WORD`.

## Related [#related]

- [Logical & Bit Instructions (Ladder)](https://rungs.dev/docs/ladder-logic/instructions/logical) — `SWPB` as a
  ladder box, beside `AND`, `OR`, `XOR` and `NOT`
- [COP](https://rungs.dev/docs/structured-text/instructions/cop-cps) — copy registers into a STRING once their bytes are in order