Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

[SOLVED]Question about getting user input(IA32)


  • Please log in to reply
7 replies to this topic

#1 restin84

restin84

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Programming Language:C, Java, C++
  • Learning:PHP, Python, Assembly

Posted 29 October 2012 - 07:49 PM

Hi guys. I'm having a little trouble getting user input in an assignment I have for my computer organization class. The program is in ia32. I have to read in a array size(local to main), and array elements(global array). We've been using 'call' in order to utilize the C language I/O functions printf and scanf.How do I use scanf to set the contents of a register to the input provided?What I've been trying is
.comm A,100,4 #array A[]/************************************************************************//****************************READ-ONLY-DATA******************************/.section .rodata.align 4str1: .string "Enter size of array: "frmt1: .string "%d"teststr1: .string "n=%d, i=%d"teststr2: .string "\nn=%d\n"/************************************************************************//****************************MAIN-FUNCTION*******************************/.text #text section.global main #declare main as globalmain:pushl %ebp #prolog save old %ebpmovl %esp, %ebp #prolog set new %ebpmovl $0, %eax #int i = 0movl $0, %ecx #int n = 0pushl $str1call printfaddl $4, %esppushl %ecx //<-----------I think my problem may be here? But I'm not sure of the fixpushl $frmt1call scanfaddl $8, %esppushl %ecxpushl $teststr2call printfaddl $8, %espleave #epilogret #epilog
I'm getting a segmentation faultI will also need to do the same thing to set the values for the array elements. What am I doing wrong?
  • 0

#2 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 29 October 2012 - 08:14 PM

scanf() can't store to a register. You need to create a variable in memory and push the address of that variable to the stack, then load that variable into ECX.
  • 1

sudo rm -rf / && echo $'Sanitize your inputs!'


#3 restin84

restin84

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Programming Language:C, Java, C++
  • Learning:PHP, Python, Assembly

Posted 29 October 2012 - 08:27 PM

So I have to create that in the bss segment for uninitialized gobal data? or say something like .comm n,4,4, in main put "movl n, %ecx" after I have set the value of n with scanf?

I did this and it works
    .comm A,100,4        #array A[]
    .comm m,4,4        #use to initialize local variable n
/************************************************************************/
/****************************READ-ONLY-DATA******************************/
    .section    .rodata
    .align 4
str1:    .string    "Enter size of array: "
frmt1:    .string    "%d"

    
teststr1:    .string "n=%d, i=%d"
teststr2:    .string    "n=%d"
/************************************************************************/    
/****************************MAIN-FUNCTION*******************************/
    .text            #text section
.global    main            #declare main as global
main:
    pushl    %ebp        #prolog save old %ebp
    movl    %esp, %ebp    #prolog set new %ebp
    movl    $0, %eax    #int i = 0
    movl    $0, %ecx    #int n = 0

    pushl    $str1
    call    printf
    addl    $4, %esp

    pushl    $m
    pushl    $frmt1
    call    scanf
    addl    $8, %esp
    movl    m, %ecx

    pushl    %ecx
    pushl    $teststr2
    call    printf
    addl    $8, %esp
    
    leave            #epilog
    ret            #epilog
 

  • 0

#4 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 29 October 2012 - 08:44 PM

You don't need to create a BSS section just for that; if it's only going to be used locally, you can create the variable on the stack.
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'


#5 restin84

restin84

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Programming Language:C, Java, C++
  • Learning:PHP, Python, Assembly

Posted 29 October 2012 - 08:50 PM

Hmmm. I'm not quite sure I know how to do that.
  • 0

#6 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 29 October 2012 - 09:10 PM

To create 8 bytes' worth of variables (e.g. two integers on a 32-bit machine) you subtract 8 from ESP right after the movl %esp, %ebp instruction. Now you have two integer variables, one at %esp, and the next at %esp + 4. You can also consider that as four 16-bit shorts, 8 characters, etc. Whatever fits in there.

Alternatively, instead of doing this:
pushl %ebp
movl %esp, %ebp
subl $8, %esp

You can do this:
enter $8, $0

The first number is the number of bytes you want to allocate on the stack; the second number should be 0 except for specialized purposes, which I won't get into unless you want me to. If you use enter you should use leave; the converse isn't necessarily true, but I recommend either doing the push/move/subtract method or using enter/leave, not mixing the two.
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'


#7 restin84

restin84

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Programming Language:C, Java, C++
  • Learning:PHP, Python, Assembly

Posted 29 October 2012 - 09:27 PM

I will probably go with the first option. So how do I reference that area of memory to push it onto the stack before I call scanf?
Is it something like
pushl (%esp)
pushl $somestring
call scanf

Thanks for the help by the way.

  • 0

#8 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 29 October 2012 - 09:32 PM

For the first variable on the stack, pushl %esp is correct (note no dereferencing). For variables further up the stack, it'd be something like
lea     edx, [esp + 4]
push    edx
This is Intel syntax, mind you, for the sake of clarity. AT&T syntax is more convoluted.
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download