Question

I'm trying to sum the ascii value's of a string from a loop. I think I'm missing something, but I keep either getting wrong values returned at the end of the program (ie. not matching the values i manually summed using the ascii table), or seg faults.

My program:

.data                           # .data section begins
name: .ascii "Json"             # name is ASCII chars (.ascii or .byte)
len:  .int 4                    # name length is 4 chars, an integer
newline: .ascii "\n"            # new line character

count: .int 0                   # counter for loop (start at 0)

return: .int 0                  # return code value
tmp: .int 0                     # temp value

.text                           # text section starts
.global _start                  # main program entry

_start:                         # start instruction

again:                          # begin loop

    mov $1, %edx                # 1 byte at a time
    mov $name, %ecx             # mem addr
    add count, %ecx             # offset in string

    #### Trouble area ####

    # this seg faults
    mov count(%ecx), %ebx
    add %ebx, return

    #### Trouble area ####

    mov $1, %ebx                # file descriptor 1 is computer display
    mov $4, %eax                # system call 4 is sys_write (output)
    int $128                    # interrupt 128 is entry to OS services

    add $1, count               # incr count
    mov count, %eax             # copy count to eax
    cmp %eax, len               #   and compare values

    jne again                   # if not equal, goto again

    mov $newline, %ecx          # mem addr

    mov $1, %ebx                # file desc 1
    mov $4, %eax                # sys call 4
    int $128                    # interrupt 128

    mov $1, %eax                # system call 1 is sys_exit
    mov return, %ebx            # status return
    int $128                    # interrupt 128

I think I'm missing something basic, but I understand this to be move the value in ecx register offset by the value of count (ie. loop iteration and therefore the array element), into register ebx. Then add the value in ebx to return. Then at the endof the program, move the summed value that is in return to register ebx and then call the interrupt. During runtime this seg faults, but I'm unsure why.

I would expect it to not seg fault (obviously lol), and when calling ~]# echo $? for it to print 410 (ie, 'J' + 's' + 'o' + 'n' or... 74 + 115 + 111 + 110).

UPDATE:------------>

I have updated the "trouble spot" to the following per advice from @Michael (if I understood correctly).

    #### Trouble area ####

    # this returns a garbage number, 154 instead of 410
    mov count, %edi 
    mov name(%edi), %ebx
    add %ebx, return

    #### Trouble area ####
Was it helpful?

Solution

Exit codes

POSIX exit status codes are effectively an unsigned byte.

#include <stdio.h>

int main() {
    printf("%d\n", (unsigned char)410);
    return 410;
}

This will both print and return 154, which is 410 % 256.

Read the POSIX section here: http://en.wikipedia.org/wiki/Exit_status#POSIX

Other ways of getting the value

  1. You can run your process in gdb and use i r to print the register contents, or print return.

  2. You can convert your int into a string [1] and call the write syscall [2] on stdout with a pointer to the resulting string (write(1, "string\n", len)).

[1] integer to string: mod 10 to get rightmost digit, divide by 10 to remove the rightmost digit, repeat until n = 0, then reverse the string or do a call to sprintf(), itoa(), etc

[2] http://asm.sourceforge.net/articles/linasm.html#Syscalls

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top