SAR moves every bit one place to the right, count times, like SHR, but the top bit is not replaced by 0: it keeps its value and is copied into the bit below it. A negative number stays negative and a positive one stays positive. The bit leaving bit 0 goes into CF.

b7 -> b7 b6 b5 b4 b3 b2 b1 b0 -> CF
(the sign bit stays and is copied right)
1111 1001 -7
SAR 1 1111 1100 -4, CF = 1

Forms and flags

Register or memory operand; count 1 or CL on the 8086. CF receives the last bit shifted out, SF ZF PF describe the result, AF is undefined. With a count of 1, OF is always 0, because the sign can never change. For other counts OF is undefined.

Pitfall: rounding

SAR divides by 2 to the power n but rounds toward minus infinity. IDIV rounds toward zero. For positive numbers they agree; for negative odd numbers they do not: -7 SAR 1 is -4, while -7 IDIV 2 is -3 with remainder -1. Shifting a negative number again and again ends at -1 (all ones), never at 0.

To get the IDIV answer from a shift, add 2^n - 1 to a negative number first. For division by 2 that is 1:

TEST AX, AX
JNS POS1
INC AX ; negative: add 2^1 - 1
POS1:
SAR AX, 1 ; now rounds toward zero, like IDIV

Idioms and later CPUs

Copying the sign across a whole register: MOV DX, AX, MOV CL, 15, SAR DX, CL leaves DX = 0000h or FFFFh, the same as CWD. The 8086 uses all 8 bits of CL; the 80186 and later mask the count to 5 bits and accept an immediate count.

Prints 11111001 11111100 CF=1 01111100
MOV AL, -7 ; F9h = 1111 1001
CALL SHOWBIN
SAR AL, 1 ; 1111 1100 = -4
CALL SHOWBIN
CALL SHOWCF ; the bit that fell out
MOV AL, -7
SHR AL, 1 ; 0111 1100 = 124: the sign is lost
CALL SHOWBIN
SHOWBIN PROC NEAR ; print AL as 8 binary digits and a space
PUSHF ; keep the caller's flags
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BL, AL
MOV CX, 8
NEXTBIT:
SHL BL, 1 ; the top bit falls into CF
MOV DL, "0"
ADC DL, 0 ; "0" + CF = "0" or "1"
MOV AH, 02h
INT 21h
LOOP NEXTBIT
MOV DL, " "
MOV AH, 02h
INT 21h
POP DX
POP CX
POP BX
POP AX
POPF
RET
SHOWBIN ENDP
SHOWCF PROC NEAR ; print "CF=0" or "CF=1" and a space
PUSHF
PUSH AX
PUSH DX
MOV DL, "0"
ADC DL, 0 ; "0" + CF, before anything changes CF
PUSH DX
MOV AH, 09h
MOV DX, OFFSET CFTXT
INT 21h
POP DX
MOV AH, 02h
INT 21h
MOV DL, " "
MOV AH, 02h
INT 21h
POP DX
POP AX
POPF
RET
SHOWCF ENDP
CFTXT DB "CF=$"