Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appending two string in x86 assembly

I'm currently working on an assignment in AT&T Assembly and now I have to append two strings:

message: .asciz "String 1"
before: .asciz "String 2"

I have really no idea how to do this or how to begin. I've already searched on internet but I couldn't find any helpful information. I think I have to manually copy the characters of the second string to the end of the first string but I'm not sure about that.

Could anyone please explain to me how to do this? :)

like image 718
Devos50 Avatar asked Jun 05 '12 10:06

Devos50


People also ask

How do you concatenate 2 strings?

Concatenation is the process of appending one string to the end of another string. You concatenate strings by using the + operator. For string literals and string constants, concatenation occurs at compile time; no run-time concatenation occurs.

What happens when 2 strings are added?

In Java, String concatenation forms a new String that is the combination of multiple strings.

How do I compare two strings in x86 assembly?

For comparing strings in x86-assembly there is a special OpCode named CMPS (Compare Strings). In your case of BYTE strings the relevant OpCode is CMPSB . You do use it by setting ESI to the source string and EDI to the destination string. The length of the equality check (preferrably the longest string) is set in ECX .

Does C support string concatenation?

In C, the strcat() function is used to concatenate two strings. It concatenates one string (the source) to the end of another string (the destination). The pointer of the source string is appended to the end of the destination string, thus concatenating both strings.


1 Answers

This question fails to mention the target memory, which makes it somewhat difficult to answer. I also don't know if you're in 16 bit, 32 bit or 64 bit. For convenience's sake, I'll also just assume they're C style 0-terminated strings.

Anyway, this seems to be the general procedure:

  • Get the length of the first string (instructions on writing an asm strlen can be found here: http://www.int80h.org/strlen/)
  • Set the ptr to the target memory
  • Copy the first string to the destination memory, using rep(e/ne) movsb with the size in ecx.

This can be CPU-optimized by using 'movsd' by first doing a shr ecx, 2 on your length to get it in batches of 4 bytes, and then doing the remainder with movsb. I've seen this done like this:

mov     edi, dest
mov     esi, string_address
mov     ecx, string_length
mov     eax, ecx
shr     ecx, 2
repne movsd
mov     cl, al
and     cl, 3
repne movsb ; esi and edi move along the addresses as they copy, meaning they are already set correctly here
  • Get the length of the second string (be sure to back up your edi in stack or another register if needed; it contains the address you need to copy the next string to)
  • Copy the second string to the destination memory (as I said, the correct address should be in edi after the first string operation)
  • For safety, add a new 0 behind it.

If you're copying the second string to the end of the first string, you need one less copy operation, but you have to make sure there is actually enough space there to copy the second string without overwriting other vital stuff.

like image 82
Nyerguds Avatar answered Sep 28 '22 00:09

Nyerguds