Quantcast
Viewing all articles
Browse latest Browse all 6

Comparing Strings in Assembly

Image may be NSFW.
Clik here to view.
Edit
As part of my quest to improve my assembly skills I’ve been reviewing Vivek Ramachandran’s Assembly Primer for Hackers. I’ve nearly completed the series and I thought I would try out some of what I learned. I did my best to write this code completely from scratch and without reviewing the videos at all. I did peek at Professor Ben Abdallah’s reference guide to decide which loop instruction was appropriate and how to jump to the correct label after using cmp, but I didn’t feel like I was having to learn the material; it was used as a reference guide just as it was intended.

String Comparison

This string comparison example is very basic. The strings being compared are stored in Str1 and Str2 directly in the .data section of the code. They are not passed in as parameters as you would normally want for reusability. This was designed based only on the bits of assembly I’ve reviewed thus far and I’m only just now about to review writing proper functions. This is also why you’ll also see jmp instructions here instead of the call instruction. However, I will pride myself in having this work on the first try after writing it completely from scratch (no errors)! Not bad considering I’m just now getting better acquainted with assembly!

The code

This will print out “Strings are equal!” when executed. If you modify Str1 or Str2 so that they are not equal, you will see “Strings are not equal!” instead; depending on the modifications you make you may have to adjust the ECX register since it contains the string length.

.data
    Str1:
        .asciz "abcdefghij"
    Str2:
        .asciz "abcdefghij"
    StrEqual:
        .asciz "Strings are equal!\n"
    StrNotEqual:
        .asciz "Strings are not equal!\n"

.text
    .globl _start

    _start:
        nop

    StrCmp:
        leal Str1, %esi
        leal Str2, %edi
        movl $11, %ecx # length of the strings to compare
        cld
        ContinueCmp:
            cmpsb
        loopz ContinueCmp
        cmp $0, %ecx
        jz PrintEqual
        jmp PrintNotEqual

    ExitProgram:
        movl $1, %eax
        movl $0, %ebx
        int $0x80

    PrintNotEqual:
        movl $4, %eax
        movl $1, %ebx
        leal StrNotEqual, %ecx
        movl $24, %edx
        int $0x80
        jmp ExitProgram

    PrintEqual:
        movl $4, %eax
        movl $1, %ebx
        leal StrEqual, %ecx
        movl $20, %edx
        int $0x80
        jmp ExitProgram

Some pseudo-code to explain what’s going on

* Program starts at _start
* The nop is just for debugging; it does nothing useful
* Using leal (load effective address) we make ESI and EDI pointers to Str1 and Str2 respectively
* We're going to loop over each character in each string, so the length of an individual string is loaded into the ECX register (11)
* Running cmpsb will set ZF (the zero flag) if the characters compared are equal
    * ESI and EDI will both be incremented, so every time cmpsb runs we are comparing the next character in each string
* The loopz instruction effectively means "if ZF is set and ecx is not 0, run cmpsb again"
    * More humanly, if the characters compared are equal and we're not at the end of the string, compare the next characters in the string"
* Once the loop ends, we need to know why it ended; were we at the end of the string or did we find characters that didn't match?
    * By using cmp, we check if ECX is 0; if ECX is 0 we're at the end of the string, otherwise the loop ended early so we have a character mismatch
* If we were at the end of the string ZF will be set because ECX will equal 0; if this is all true, jz will take us to PrintEqual
* If the above is not true, we jmp to PrintNotEqual
* Both of the Print labels just call the write() system call to print a string and then jmp to ExitProgram
* ExitProgram calls the exit() system call with a status of 0

Viewing all articles
Browse latest Browse all 6

Trending Articles