Lesson 15-String Manipulation Instructions and Comprehensive Applications

String Manipulation Instructions and Comprehensive Applications

If you’ve ever wondered how memcpy can copy 1 GB of data in a fraction of a second, or how strlen can scan a string faster than a simple C loop — the answer often lies in the x86 string manipulation instructions. These are dedicated CPU instructions (MOVSB, STOSB, CMPSB, SCASB, LODSB) that are optimized at the microarchitectural level to operate on memory efficiently.

In this article, we’re going to dissect every string instruction, understand exactly how they work, learn when to use them (and when NOT to), and implement the entire C standard library string functions from scratch. By the end, you’ll be able to write assembly code that rivals — or beats — your C compiler’s output.

Why String Instructions Exist: Operating on Arrays/Memory Blocks Is So Common That CPUs Have Dedicated Instructions

Let’s start with a fundamental observation: a LOT of what computers do is move data around. Copying memory (memcpy), setting memory (memset), comparing memory (memcmp), searching for a character (strchr) — these are some of the most common operations in computing.

The Intel 8086 designers recognized this back in 1978. They added five instructions (LODS, STOS, MOVS, CMPS, SCAS) plus the REP prefix to make these operations fast and compact.

The Problem: Manual Loops Are Slow and Verbose

Without string instructions, copying memory in assembly looks like this:

; Copy RCX bytes from RSI to RDI (manual loop)
copy_loop:
    mov al, [rsi]
    mov [rdi], al
    inc rsi
    inc rdi
    dec rcx
    jnz copy_loop

That’s 7 instructions for a simple copy. Now compare with the string instruction version:

; Copy RCX bytes from RSI to RDI (string instruction)
rep movsb

One instruction! (Well, one instruction plus the REP prefix, but it assembles to just a few bytes.)

The Solution: Microcode Optimizations

But the real magic isn’t just code size — it’s performance. The REP MOVSB instruction is implemented in microcode (firmware inside the CPU) and has been heavily optimized over decades:

  1. Pentium+: REP MOVSB checks for alignment and uses wider transfers (32-bit or 64-bit) internally when possible.
  2. Core 2+: REP MOVSB is “fast string” optimized — it can copy 16 bytes at a time using internal 128-bit operations.
  3. Ice Lake+: REP MOVSB can use EVX-512 to copy 64 bytes at a time!

So REP MOVSB doesn’t actually copy one byte at a time. The CPU dynamically chooses the optimal transfer size based on alignment, size, and CPU capability.

When to Use String Instructions vs SIMD

You might ask: “If REP MOVSB is so fast, why does anyone use SSE/AVX for memcpy?”

Great question. Here’s the tradeoff:

ScenarioBest ApproachWhy
Small copies (< 128 bytes)REP MOVSBLess setup overhead
Medium copies (128 bytes – 4KB)REP MOVSB or unrolled MOVSQREP MOVSB is surprisingly fast here
Large copies (> 4KB)SSE2/AVX2 MOVDQU + loopCan be faster for very large sizes on some CPUs
Copy with known alignmentMOVSD/MOVSQ (manual loop)Avoids alignment checks
Variable-sized copyREP MOVSBHandles everything in one instruction

Rule of thumb: For general-purpose memcpy, REP MOVSB is a solid choice. For performance-critical code where you know the sizes in advance, hand-optimized SSE2/AVX2 can be faster.

Membership Required

You must be a member to access this content.

View Membership Levels

Already a member? Log in here

Share your love