Search code examples
stringassemblyintegerx86-64att

Loop Segmentation Fault


This is my code so far.

            .data
S:          .string "-149"
Length:     .byte   -1
Result:     .quad 

            .text
            .globl main

main: 
    mov     S,%rdx              #Storage of string, counter, position and result in memory
    mov     Length, %rcx
    mov     Result, %rax
    mov     $10, %r10
    mov     $30, %r13
    mov     $-1, %r9

Loop1:                          #loop string from beginning to end  
    cmp     $0,0(%rdx)          #compare base addresss value with null
    je      Counter_Made        #if null, branch to end loop. 
    add     %r14, Length        #increment length by for each digit thats not null (creates counter for 2nd loop)
    add     $1, %rdx            #increment base by 1 to move onto next digit in string
    jmp     Loop1               #reinitiate loop


Counter_Made: 
    cmp     %r15,Length         #check if length is zero
    je      Output              #End program, output null result
    cmp     %r15,Length(%rdx)   #Determine negativity/positivity of integer
    jl      Negative_counter
    jmp     Positive_loop 

Positive_loop: 
    cmp     %r9,Length          #End of loop check 
    je      Output              #Store result if loop end condition satisfied
    mov     %r10, Length(%rdx)  #Store byte of integer in supplementary register
    sub     %r13,  %r10         #Conversion from 8bitASCII to 2Bit Binary
    imul    %r11, %r10          #Place holder multiplication 
    add     %r10, %rax          #Store cumulative addition in memory
    sub     %r14, Length        #Length decrement 
    jmp     Positive_loop       #reloop

Negative_counter:
    sub     %r14,Length
    jmp     Negative_loop

Negative_loop: 
    cmp     %r9,Length
    je      Negative_Complement 
    mov     %r10, Length(%rdx)  #Store byte of integer in supplementary register
    sub     %r13, %r10          #Conversion from 8bitASCII to 2Bit Binary
    imul    %r10, %r10          #Place holder multiplication 
    add     0(%rdx), %rax       #Store cumulative addition in memory
    sub     %r14, Length
    jmp     Negative_loop

Negative_Complement:
    not     %rdx                #Convert to 2's complement with negation and then + 1
    add     %r14,%rdx
    jmp     Output

Output:
    mov      %rdx, Result 
    ret 
#size mismatch for imul 
#Specific place in memory to put output or no?

The code is supposed to convert a character string that represents any signed integer to its 2’s complement value.

I'm receiving a segmentation fault in one of my loops and I've tried multiple different methods here but to no avail - could anyone explain how I should about fixing this segfault? I'm stumped.

Here is the GDB errors

Program received signal SIGSEGV, Segmentation fault.
Loop1 () at data.s:18
18      cmp     $0,0(%rdx)          #compare base addresss value with null

This is the second error.

Counter_Made () at data.s:28
28      cmp     $0,Length(%rdx)     #Determine negativity/positivity of integer, if <0 value is negative

I'm suspecting its the Length(%rdx) method that I'm trying to interpret the loop with. Would it be better to sub $1,%rdx


Solution

  • You want

    mov $S,%edx
    

    to load the address of the string into %rdx. This works because the program image is always loaded into the lower 4 GB of the address space. Alternatively, you can use a %rip relative lea to load the address even if the process image is loaded outside of the first 4 GB:

    lea S(%rip),%rdx
    

    but that instruction has a somewhat longer encoding (two extra bytes).

    The instruction

    mov S,%rdx
    

    loads the first eight bytes of the memory S points to into %rdx, which is not what you want.