Thread: Strcpy Assembly

  1. #1
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629

    Strcpy Assembly

    Hi,
    ok I am probably gonna get my butt kicked for this...but I don't know where to post this question, I figured C is closer to Assembly. And you guys must have done it, since I have to
    Code:
          .section .data 
    
          .section .text  
    
          .global _start
    
           stringVar: 
                .asciz "Hello World0" 
           copyString: 
                .byte 12 
           
           _start:
                movl $stringVar, %esi 
                movl $copyString, %edi
                movl $0,%ebx
    
    
            copyLoop:
                cmpl $12,%ebx
                je exit
                movb (%esi), %cl
                movb %cl, (%edi)
                incl %esi
                incl %edi 
                incl %ebx 
                jmp copyLoop
    
    
           exit: 
                movl $1, %eax
                int $0x80


    For some reason I keep getting a seg fault whenever I attempt to move the content of %cl to %edi

    I am not sure why that is happening as I have allocated 12 bytes to copyString and edi points to the first element...
    I would like any help
    thanks!
    You ended that sentence with a preposition...Bastard!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    "Hello World" requires at least 13 bytes (that's counting from one), because of the terminating zero. The zero goes into the twelfth subscript.

  3. #3
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by whiteflags View Post
    "Hello World" requires at least 13 bytes (that's counting from one), because of the terminating zero. The zero goes into the twelfth subscript.
    but "Hello World" is 11 characters, +1 for the terminating zero. So 12bytes? counting from 1
    so in assembly it doesn't start from 0....
    I changed it to 13 bytes but i still get a seg fault
    I believe it is this line
    Code:
    movb %cl, (%edi)
    but I don't know why
    You ended that sentence with a preposition...Bastard!

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by whiteflags View Post
    "Hello World" requires at least 13 bytes (that's counting from one), because of the terminating zero. The zero goes into the twelfth subscript.
    I only count 12 bytes.

    I think you get the crash because you are attempting to write to the .text section. You should declare your copyString in the .data section instead. It's been a long time since I've done any assembly though, so I could be wrong.
    bit∙hub [bit-huhb] n. A source and destination for information.

  5. #5
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    oh ja.
    gut idee.
    Will try it out now! Danke!
    You ended that sentence with a preposition...Bastard!

  6. #6
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Oh my God. I can't believe it. It worked...

    Well I am not getting seg faults, but I can't see the output. I only know that %ebx has the value of 12 the length of the string.
    Any ideas on how to use sys calls to output data or input data?

    I don't understand the intel syntax and can't find anything on AT&T sys calls.
    Thanks!
    You ended that sentence with a preposition...Bastard!

  7. #7
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I believe that printing will depend on what operating system you are running this on.
    bit∙hub [bit-huhb] n. A source and destination for information.

  8. #8
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    I am using Debian on Windows 7 through virtual box.


    our lecture gave us some numbers as syscalls
    1 was for exit and it seems to exit fine and

    when i try 3 and 4(read and write )

    Code:
    
             movl $4, %eax 
             int $0x80
    it doesn't display anything...
    EDIT:
    I managed to get some response with this code:

    Code:
    hello: 
           .string "World" 
    
    exit: 
           movl $6, %edx        #move length to register
           movl $0, %ebx        #file handle to display to screen
           movl $hello, %ecx      #move address of label to ecx 
           movl $4, %eax           #call display interrupt subrouting..
    It prints "ello" instead of "World"...
    Any ideas ?
    Last edited by Eman; 12-30-2010 at 07:58 PM.
    You ended that sentence with a preposition...Bastard!

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    .asciz "Hello World0"
    You don't need that zero at the end. That's actually an ASCII character zero in your string, making it 13 chars (including the null), as whiteflags stated. The asciz directive will null terminate the string for you. The ascii directive requires you put in your own null.

    Incidentally, your copy function always copies 12 bytes, regardless of how long the string is, instead of copying until it finds a null character. Is that what you wanted/were required to do?

    As for your print code, you have the right system calls for linux: System Call Table. The code works fine for me. Is that mixed in with your copy function? Did you somehow overflow into your hello label? Try the following:
    Code:
    .section .data
    
    hello:
        .string "World"
    .section .text
    
    .global _start
    
    _start:
           movl $6, %edx
           movl $0, %ebx
           movl $hello, %ecx
           movl $4, %eax
        int $0x80
    
        movl $1, %eax
        int $0x80

  10. #10
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    The asciz directive will null terminate the string for you. The ascii directive requires you put in your own null.
    so there .ascii then. Good to know

    Incidentally, your copy function always copies 12 bytes, regardless of how long the string is, instead of copying until it finds a null character. Is that what you wanted/were required to do?
    Yeah that's what I wanted, but when I got the seg fault. I changed the base case (%ebx) to be 12.
    As for your print code, you have the right system calls for linux: System Call Table. The code works fine for me. Is that mixed in with your copy function? Did you somehow overflow into your hello label? Try the following:
    Code:
            movl $6, %edx
           movl $0, %ebx
           movl $hello, %ecx
           movl $4, %eax
           int $0x80
    
            movl $1, %eax
            int $0x80
    That still doesn't work.

    This is the modified code..It still prints "ello" instead of "World"
    Code:
    .section .data 
    
    stringVar: 
    	.string "Hello World" 
    copyString: 
    	.byte 12
    	
    hello: 
    	.string "World" 
    .section .text
    
    .global _start
    
    _start:
    	movl $stringVar, %esi 
    	movl $copyString, %edi
    	movl $0,%ebx
    
    
    copyLoop:
    	cmpl $12,%ebx
    	je exit
    	movb (%esi), %cl
    	movb %cl, (%edi)
    	incl %esi
    	incl %edi 
    	incl %ebx 
    	jmp copyLoop
    	
    
    exit: 
    	movl $5, %edx 
    	movl $0, %ebx
    	movl $hello, %ecx 
    	movl $4, %eax 
    	int $0x80
    	movl $1, %eax
    	int $0x80
    Thanks.
    Last edited by Eman; 12-31-2010 at 03:43 AM.
    You ended that sentence with a preposition...Bastard!

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    That still doesn't work.
    That was meant as a standalone program, and should work fine all by itself. The problem is integrating that bit with your other code.

    Code:
    copyString: 
    	.byte 12
    This declares copyString to be a single byte with value 12. I didn't realize this until I looked at the disassembled executable your code produced (Checkout 'objdump', a very handy tool for such tasks):
    $ objdump -s -t -j .data a.out

    a.out: file format elf32-i386

    SYMBOL TABLE:
    080491bc l d .data 00000000 .data
    080491bc l .data 00000000 stringVar
    080491c8 l .data 00000000 copyString
    080491c9 l .data 00000000 hello


    Contents of section .data:
    80491bc 48656c6c 6f20576f 726c6400 0c576f72 Hello World..Wor
    80491cc 6c6400 ld.
    Notice that copy string is only one byte. It starts at address 080491d8 and is followed by hello at address 080491c9. Then, if you track that down in the data section, you see that byte has a hex value of 0c, or decimal 12. Your copy loop copied 12 bytes, starting at copyString, and running clear on into hello, hence the "ello". Try the following declaration for stringVar:
    Code:
    .comm copyString,12,1
    That declares a symbol copyString to be 12 bytes, on 1-byte alignment. Should do the trick for you.

  12. #12
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by Eman View Post
    so there .ascii then. Good to know


    Yeah that's what I wanted, but when I got the seg fault. I changed the base case (%ebx) to be 12.

    That still doesn't work.

    This is the modified code..It still prints "ello" instead of "World"
    Code:
    .section .data 
    
    stringVar: 
    	.string "Hello World" 
    copyString: 
    	.byte 12
    	
    hello: 
    	.string "World" 
    .section .text
    
    .global _start
    
    _start:
    	movl $stringVar, %esi 
    	movl $copyString, %edi
    	movl $0,%ebx
    
    
    copyLoop:
    	cmpl $12,%ebx
    	je exit
    	movb (%esi), %cl
    	movb %cl, (%edi)
    	incl %esi
    	incl %edi 
    	incl %ebx 
    	jmp copyLoop
    	
    
    exit: 
    	movl $5, %edx 
    	movl $0, %ebx
    	movl $hello, %ecx 
    	movl $4, %eax 
    	int $0x80
    	movl $1, %eax
    	int $0x80
    Thanks.
    Quote Originally Posted by anduril462 View Post
    That was meant as a standalone program, and should work fine all by itself. The problem is integrating that bit with your other code.

    Code:
    copyString: 
    	.byte 12
    This declares copyString to be a single byte with value 12. I didn't realize this until I looked at the disassembled executable your code produced (Checkout 'objdump', a very handy tool for such tasks):

    Notice that copy string is only one byte. It starts at address 080491d8 and is followed by hello at address 080491c9. Then, if you track that down in the data section, you see that byte has a hex value of 0c, or decimal 12. Your copy loop copied 12 bytes, starting at copyString, and running clear on into hello, hence the "ello". Try the following declaration for stringVar:
    Code:
    .comm copyString,12,1
    That declares a symbol copyString to be 12 bytes, on 1-byte alignment. Should do the trick for you.
    Thanks for the quick reply!
    So I declared a char instead, instead of a string..
    but I still don't get why it prints "ello"
    if the loop goes 12 times, which it does,
    shouldn't it have overwritten everything?

    but it is still printing the wrong thing out..the label, "Hello", not the string itself.
    You ended that sentence with a preposition...Bastard!

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't know what you mean by "declared a char instead, instead of a string", probably because I'm not sure what variable you're talking about.

    I'm really not sure what you're attempting to do, or what you want to see. As to the printing, you copy to copyString and print the string Hello. The only reason the string Hello has changed from its original "World" is because copyString isn't long enough to hold the whole thing and so you've tromped on your memory there. You only see "ello" and not the whole thing because you only print 5 characters.

  14. #14
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    No, it's not printing out the label. If it did print out your label, why would there be a space at the end of "ello " and no 'h' at the beginning? Your reasoning is all backwards. You've made up a crazy scenario to fit your unexpected results instead of finding out the far more likely case of why the data stored at hello is now "ello " instead of "World". If you want further proof, change it to print out 10 bytes. Or better yet, change the contents of stringVar to "Not a label!" and see if it still prints "ello ". Or change the label hello to thiswontprint.

    The most important thing to learn from all this is how to analyze what your code is doing logically. Your memory layout has a single byte for copyString followed immediately by the string labelled hello (contents "World"). You copied 12 bytes from stringVar into the address starting at copyString. The first byte of stringVar, the 'H', is copied into the byte you reserved for copyString. The next byte from stringVar, the 'e' is copied to the byte after copyString, which is the start of hello. Then the 'l' is copied into the byte after that (second byte of hello), etc. At the end of it all you print 5 bytes starting at hello, which now contains the part of stringVar that overflowed when you tried to copy 12 bytes into the single byte copyString.

  15. #15
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by anduril462 View Post
    No, it's not printing out the label. If it did print out your label, why would there be a space at the end of "ello " and no 'h' at the beginning? Your reasoning is all backwards. You've made up a crazy scenario to fit your unexpected results instead of finding out the far more likely case of why the data stored at hello is now "ello " instead of "World". If you want further proof, change it to print out 10 bytes. Or better yet, change the contents of stringVar to "Not a label!" and see if it still prints "ello ". Or change the label hello to thiswontprint.

    The most important thing to learn from all this is how to analyze what your code is doing logically. Your memory layout has a single byte for copyString followed immediately by the string labelled hello (contents "World"). You copied 12 bytes from stringVar into the address starting at copyString. The first byte of stringVar, the 'H', is copied into the byte you reserved for copyString. The next byte from stringVar, the 'e' is copied to the byte after copyString, which is the start of hello. Then the 'l' is copied into the byte after that (second byte of hello), etc. At the end of it all you print 5 bytes starting at hello, which now contains the part of stringVar that overflowed when you tried to copy 12 bytes into the single byte copyString.
    oh yeah. I see what you mean. I changed the string "Hello World" to "Oh crap" and it printed out "Oh cra"
    but even changing it to what you suggested didn't work.
    Code:
    .comm Copystring,12,1
    i don't get what you mean by '1' as a byte alignment. Does it mean each byte of the 12 is exactly one byte? So if it was an integer type we could say
    Code:
            .comm CopyString,12,4
    You ended that sentence with a preposition...Bastard!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. loading 2 character arrays in a row
    By rivkyfried1 in forum C Programming
    Replies: 4
    Last Post: 12-09-2010, 10:40 AM
  2. C to assembly interface
    By Roaring_Tiger in forum C Programming
    Replies: 4
    Last Post: 02-04-2005, 03:51 PM
  3. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. C,C++,Perl,Java
    By brusli in forum C Programming
    Replies: 9
    Last Post: 12-31-2001, 03:35 AM