1

Assembly language program to read in a (three-or-more-digit) positive integer as a string and convert the string to the actual value of the integer.

Specifically, create a subroutine to read in a number. Treat this as a string, though it will be composed of digits. Also, create a subroutine to convert a string of digits to an integer.

Do not have to test for input where someone thought i8xc was an integer.

I am doing it like this. Please help.

.section .data
  
String:
     .asciz "1234"

Intg:
     .long 0
  
.section .text
     .global _start

_start:  
     movl    $1, %edi
     movl    $String, %ecx

character_push_loop:
     cmpb $0, (%ecx)
     je conversion_loop
     movzx (%ecx), %eax        # move byte from (%ecx) to eax
     pushl %eax                # Push the byte on the stack
     incl %ecx                 # move to next byte
     jmp character_push_loop   # loop back

conversion_loop:
     popl    %eax            # pop off a character from the stack
     subl    $48, %eax       # convert to integer
     imul    %edi, %eax      # eax = eax*edi 
     addl    %eax, Intg     
     imul    $10, %edi
     decl    %ecx
     cmpl    $String, %ecx   # check when it get's to the front %ecx == $String
     je      end             # When done jump to end
     jmp     conversion_loop

end:   
     pushl   Intg
     addl    $8, %esp         # clean up the stack
     movl    $0, %eax         # return zero from program
     ret

Also, I am unable to get the output. I am getting a Segmentation Fault. I am not able to find out what is the error in my code.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847

1 Answers1

2

Proper interaction with operating system is missing.
In the end: you pushed the result but the following addl $8, %esp invalidates the pushed value and the final ret incorrectly leads the instruction flow to whatever garbage was in the memory pointed by SS:ESP+4 at the program entry.

When you increase the stack pointer, you cannot rely that data below ESP will survive.

Your program does not interact with its user, if you want it to print something, use system function to write.

print_String:
    mov  $4,eax     ; System function "sys_write".
    mov $1,ebx      ; Handle of the standard output (console).
    mov $String,ecx ; Pointer to the text string.
    mov $4,edx      ; Number of bytes to print.
    int 0x80        ; Invoke kernel function.

end:mov $1,eax      ; System function "sys_exit".
    mov (Intg),ebx  ; Let your program terminate gracefully with errorlevel Intg.
    int 0x80        ; Invoke kernel function.
vitsoft
  • 5,515
  • 1
  • 18
  • 31
  • can you please tell me why the code does not print anything like 1234? – user16567153 Aug 08 '21 at 13:49
  • 1
    @user16567153 It doesn't print anything because you didn't command Linux to print something. Look at https://stackoverflow.com/questions/20466018/how-to-print-a-single-ascii-char – vitsoft Aug 08 '21 at 14:22
  • I am unable to understand the link you provided. Can you please edit the code and include the printing command? – user16567153 Aug 08 '21 at 17:41
  • So, I just add this whole print_string above the character_push_loop section. And, it will print 1234 right? – user16567153 Aug 08 '21 at 19:26
  • 1
    @user16567153: Test your code yourself if you want to know whether it works. (Including single-step in a debugger, and/or running `strace ./a.out` to see what system calls you make). – Peter Cordes Aug 08 '21 at 20:16