Page 1 of 1

MASM : Using 'String' Instructions

#1 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Posted 21 April 2011 - 10:31 PM

MASM : Using 'String' Instructions

Introduction

The x86-64 processor has a number of instructions that provide the programmer with the ability to manipulate 'strings' at a byte, word, double and quadruple word length. These instructions are stos, movs, cmps and scas combined with the rep instruction (seen from a practical perspective, the cmps and scas instructions are never used with the rep instruction but are used with the repe and repne instructions). All these instructions are affected by the direction bit in the control register. If the direction bit is set 0, then the operation is forwards in memory, and if the direction bit is set 1, then the operation is backwards in memory.

This tutorial looks at the more common use of these instructions, seen from a 32- and 64-bit perspective (whenever I refer to a register, I will give the 64-bit register in parenthesis e.g. esi(rsi)).

Using The REP STOS Instruction

The rep stosb instruction stores the contents of the al register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by one. This operation is repeated until the ecx(rcx) register is zero.

The rep stosw instruction stores the contents of the ax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by two. This operation is repeated until the ecx(rcx) register is zero.

The rep stosd instruction stores the contents of the eax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by four. This operation is repeated until the ecx(rcx) register is zero.

The rep stosq instruction stores the contents of the rax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by eight. This operation is repeated until the ecx(rcx) register is zero.

The instruction requires that:

  • the edi(rdi) register contain the start address of the operation,
  • the al (ax, eax, rax) register contains the value to be stored, based on the size of the operation
  • the ecx(rcx) register contain the count of the operation


For example, say we wanted to set 10 bytes of a buffer to the space (0x20) character. This would be performed as follows:

    mov    al, 020H         ; Load the al register with the space byte
    lea    edi, buffer      ; Load the buffer start address
    mov    ecx, 10          ; Load the operation count
    rep    stosb            ; Store the byte into the buffer



Using The REP MOVS Instruction

The rep movsb instruction moves the contents of the memory location pointed to by the esi(rsi) register to the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by one. This operation is repeated until the ecx(rcx) register is zero.

The rep movsw instruction moves the contents of the memory location pointed to by the esi(rsi) register to the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by two. This operation is repeated until the ecx(rcx) register is zero.

The rep movsd instruction moves the contents of the memory location pointed to by the esi(rsi) register to the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by four. This operation is repeated until the ecx(rcx) register is zero.

The rep movsq instruction moves the contents of the memory location pointed to by the esi(rsi) register to the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by eight. This operation is repeated until the ecx(rcx) register is zero.

The instruction requires that:

  • the esi(rsi) register contain the start address of the source,
  • the edi(rdi) register contain the start address of the destination,
  • the ecx(rcx) register contain the count of the operation


For example, say we wanted to move 10 bytes of a buffer to save_buffer. This would be performed as follows:

    lea    esi, buffer      ; Load the buffer start address
    lea    edi, save_buffer ; Load the save buffer start address
    mov    ecx, 10          ; Load the operation count
    rep    stosb            ; Store the byte into the buffer



Using The REPE CMPS Instruction

This instruction pair is used to compare two source strings and terminate the repeat process if a discrepancy is found or the count expires.

The repe cmpsb instruction compares the contents of the memory location pointed to by the esi(rsi) register with the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by one. The operation is terminated when either the ecx(rcx) register is zero, or the result of the comparison shows inequality.

The repe cmpsw instruction compares the contents of the memory location pointed to by the esi(rsi) register with the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by two. The operation is terminated when either the ecx(rcx) register is zero, or the result of the comparison shows inequality.

The repe cmpsd instruction compares the contents of the memory location pointed to by the esi(rsi) register with the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by four. The operation is terminated when either the ecx(rcx) register is zero, or the result of the comparison shows inequality.

The repe cmpsq instruction compares the contents of the memory location pointed to by the esi(rsi) register with the memory location pointed to by the edi(rdi) register, then increments(decrements) both the esi(rsi) and edi(rdi) register by eight. The operation is terminated when either the ecx(rcx) register is zero, or the result of the comparison shows inequality.

The instruction requires that:

  • the esi(rsi) register contain the start address of the source,
  • the edi(rdi) register contain the start address of the destination,
  • the ecx(rcx) register contain the count of the operation


For example, say we wanted to compare 10 bytes of a buffer with save_buffer. This would be performed as follows:

    lea    esi, buffer      ; Load the buffer start address
    lea    edi, save_buffer ; Load the save buffer start address
    mov    ecx, 10          ; Load the operation count
    repe   cmpsb            ; Compare the byte into the buffer



The instruction following the rep cmpsb is used to determine how the repe terminated. You would use the jecxz(jrcxz) instruction to determine if the termination was due to the ecx(rcx) counter reaching zero, or the jz, jnz, or jne instruction to determine if there was inequality.


Using The REPNE SCAS Instruction

The repne scasb instruction compares the contents of the al register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by one. This operation is repeated until either the ecx(rcx) register is zero or the memory location being compared equals the contents of the al register.

The repne scasw instruction compares the contents of the ax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by two. This operation is repeated until either the ecx(rcx) register is zero or the memory location being compared equals the contents of the ax register.

The repne scasd instruction compares the contents of the eax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by four. This operation is repeated until either the ecx(rcx) register is zero or the memory location being compared equals the contents of the eax register.

The repne scasq instruction compares the contents of the rax register at the memory location pointed to by the edi(rdi) register, then increments(decrements) the edi(rdi) register by eight. This operation is repeated until either the ecx(rcx) register is zero or the memory location being compared equals the contents of the rax register.

The instruction requires that:

  • the edi(rdi) register contain the start address of the operation,
  • the al (ax, eax, rax) register contains the value to be compared, based on the size of the operation
  • the ecx(rcx) register contain the count of the operation


For example, say we wanted to compute the length of a NULL terminated string held in buffer. This would be performed as follows:

    xor    al, al           ; Clear the al register
    lea    edi, buffer      ; Load the buffer start address
    xor    ecx, ecx         ; Clear the operation count
    dec    ecx              ; Decrement operation count 
    rep    scasb            ; Compare the byte with the buffer
    inc    ecx              ; Increment operation count
    not    ecx              ; Make length of string



The reason for the decrement and increment of the ecx register is to ensure that the scasb instruction does not terminate on the first loop execution because ecx is zero.

You have to be careful when using this instruction as if the string is not NULL terminated, the repeat will continue through memory until it finds a NULL byte or an access violation occurs.

A Few Words Of Warning Regarding The Direction Bit

If you require a rep operation to work backwards, then you use the std instruction prior to the rep ... instruction itself. Make sure that you clear the direction flag once you have completed the operation by using the cld instruction. If you forget to do this, then all subsequent rep operations will be performed backwards!!

Is This A Good Question/Topic? 1
  • +

Replies To: MASM : Using 'String' Instructions

#2 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 223
  • View blog
  • Posts: 773
  • Joined: 02-June 10

Posted 23 May 2011 - 02:12 PM

Wow, you just explained something so well that I was struggling with for so long! Thanks!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1