Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the ".s" suffix in x86 instructions?

When I disassemble the .text sections of some binaries using objdump (with both AT&T and Intel syntaxes), I sometimes see instructions with a .s suffix, for example: cmpb.s %bh,%ch, sbbl.s %edi,%edi, or adcb.s %bl,%dh.

Does the .s suffix have a valid/useful meaning (perhaps not even as a suffix), or is this an artefact of disassembling some data / padding as if it was a sequence of instructions? Thank you.

like image 995
Peter Goodman Avatar asked May 25 '13 06:05

Peter Goodman


People also ask

What is the purpose of using the suffix S in the instruction?

s instruction suffix swaps the register operands in the instruction encoding (reference).

What is MOV instruction x86?

mov — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...) The mov instruction copies the data item referred to by its second operand (i.e. register contents, memory contents, or a constant value) into the location referred to by its first operand (i.e. a register or memory).

Are all x86 instructions the same length?

x86 instructions can be anywhere between 1 and 15 bytes long. The length is defined separately for each instruction, depending on the available modes of operation of the instruction, the number of required operands and more.

What is SI and DI in assembly?

SI is called source index and DI is destination index. As the name follows, SI is always pointed to the source array and DI is always pointed to the destination. This is usually used to move a block of data, such as records (or structures) and arrays. These register is commonly coupled with DS and ES.


1 Answers

To understand what the .s suffix means, you need to understand how x86 instructions are encoded. If we take adc as an example, there are four main forms that the operands can take:

  1. The source operand is an immediate, and the destination operand is the accumulator register.
  2. The source operand is an immediate, and the destination operand is a register or memory location
  3. The source operand is a register, and the destination operand is a register or memory location.
  4. The source operand is a register or memory location, and the destination operand is a register.

And of course there are variants of these for the different operand sizes: 8-bit, 16-bit, 32-bit, etc.

When one of your operands is a register and the other is a memory location, it is obvious which of forms 3 and 4 the assembler should use, but when both operands are registers, either form is applicable. The .s prefix tells the assembler which form to use (or in the case of a disassembly, shows you which form has been used).

Looking at the specific example of adcb %bl,%dh, the two ways it can be encoded are as follows:

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

The first byte determines the form of the instruction used, which I'll get back to later. The second byte is what is know as a ModR/M byte and specifies the addressing mode and register operands that are used. The ModR/M byte can be split into three fields: Mod (the most significant 2 bits), REG (the next 3) and R/M (the last 3).

de: Mod=11, REG = 011, R/M = 110
f3: Mod=11, REG = 110, R/M = 011

The Mod and R/M fields together determine the effective address of the memory location if one of the operands is a memory location, but when that operand is just a register, the Mod field is set to 11, and R/M is the value of the register. The REG field obviously just represents the other register.

So in the de byte, the R/M field holds the dh register, and the REG fields holds the bl register. And in the f3 byte, the R/M field holds the bl register, and the REG fields holds the dh register. (8-bit registers are encoded as the numbers 0 to 7 in the order al,cl,dl,bl,ah,ch,dh,bh)

Getting back to the first byte, the 10 tells us to use the form 3 encoding, where the source operand is always a register (i.e. it comes from the REG field), and the destination operand is a memory location or register (i.e. it is determined by the Mod and R/M fields). The 12 tells us to use the form 4 encoding, where the operands are the other way around - the source operand is determined by the Mod and R/M fields and the destination operand comes from the REG field.

So the the position the registers are stored in the ModR/M byte are swapped, and the first byte of the instruction tells us which operand is stored where.

like image 194
James Holderness Avatar answered Oct 22 '22 03:10

James Holderness