Left and Right Shifts

Program ASM_ShiftDemo demonstrates the use of the SHL and SHR operators. SHL shifts all of the bits of a register or variable to the left by the number of places supplied in the other operand. The least significant bits introduced by the shift are all zeros, so each left shift doubles the value until a most significant bit of 1 is 'lost' from the left hand side of the operand.

SHR shifts all of the bits of a register or variable to the right by the number of places supplied in the other operand. The most significant bits introduced by the shift are all zeros for a positive operand, so each right shift performs the integer division-by-two (DIV 2) operation.

program ASM_ShiftDemo;
  {$APPTYPE CONSOLE}
  {$ASMMODE INTEL}  //Delete this line in Delphi
uses
  SysUtils;
var
  TestByte : byte = 55;
  ShiftLeft1, ShiftLeft2, ShiftLeft3, ShiftRight1, ShiftRight2:  byte;
begin
  asm
    MOV AL, TestByte //AL is a byte-size accumulator
    SHL AL, 1
    MOV ShiftLeft1, AL

    SHL AL, 1   //Shift another place to the left
    MOV ShiftLeft2, AL

    SHL AL, 1 //Shift another place to the left
    MOV ShiftLeft3, AL

    MOV AL, TestByte
    SHR AL, 1
    MOV ShiftRight1, AL

    MOV AL, TestByte
    SHR AL, 2
    MOV ShiftRight2, AL
  end;
  writeln(TestByte, '  ...');
  writeln('shifted one place to the left: ', ShiftLeft1);
  writeln('shifted two places to the left: ', ShiftLeft2);
  writeln('shifted three places to the left (losing leftmost 1): ', ShiftLeft3);
  writeln('shifted one place to the right: ', ShiftRight1);
  writeln('shifted two places to the right: ', ShiftRight2);
  readln;
end.

Program ASM_Bin2DecA demonstrates how to use the SHL and SHR operations using AT&T syntax.

program ASM_ShiftDemoA;
  {$mode objfpc}{$H+}
  {$ASMMODE ATT}
uses
  SysUtils;
var
  TestByte : byte = 55;
  ShiftLeft1, ShiftLeft2, ShiftLeft3, ShiftRight1, ShiftRight2:  byte;
begin
  asm
    MOV TestByte, %AL //AL is a byte-size accumulator
    SHL $0x1, %AL 
    MOV %AL, ShiftLeft1

    SHL $0x1, %AL   //Shift another place to the left
    MOV %AL, ShiftLeft2

    SHL $0x1, %AL //Shift another place to the left
    MOV %AL, ShiftLeft3

    MOV TestByte, %AL
    SHR $0x1, %AL
    MOV %AL, ShiftRight1

    MOV TestByte, %AL
    SHR $0x2, %AL
    MOV %AL, ShiftRight2
  end;
  writeln(TestByte, '  ...');
  writeln('shifted one place to the left: ', ShiftLeft1);
  writeln('shifted two places to the left: ', ShiftLeft2);
  writeln('shifted three places to the left (losing leftmost 1): ', ShiftLeft3);
  writeln('shifted one place to the right: ', ShiftRight1);
  writeln('shifted two places to the right: ', ShiftRight2);
  readln;
end.

Program ShiftDemo is an equivalent program without any assembler code.

program ShiftDemo;
  {$APPTYPE CONSOLE}
uses
  SysUtils;
var
  TestByte : byte = 55;
  ShiftLeft1, ShiftLeft2, ShiftLeft3, ShiftRight1, ShiftRight2:  byte;
begin
  ShiftLeft1 := TestByte shl 1;
  ShiftLeft2 := TestByte shl 2;
  ShiftLeft3 := TestByte shl 3;
  ShiftRight1 := TestByte shr 1;
  ShiftRight2 := TestByte shr 2;
  writeln(TestByte, ' ...');
  writeln('shifted one place to the left: ', ShiftLeft1);
  writeln('shifted two places to the left: ', ShiftLeft2);
  writeln('shifted three places to the left (losing leftmost 1): ', ShiftLeft3);
  writeln('shifted one place to the right: ', ShiftRight1);
  writeln('shifted two places to the right: ', ShiftRight2);
  readln;
end.  
Programming - a skill for life!

Getting started with in-line assembler