flat assembler
Message board for the users of flat assembler.

Index > Linux > Signed number with scanf under Gentoo 80x86_64

Author
Thread Post new topic Reply to topic
Doles



Joined: 21 Nov 2008
Posts: 4
Location: Wroclaw/Poland
Doles
Hi,
I was writting some little apps for my programming lessons at my universisty. These applications should be coded in Java and I done it. Now I`m just practicing my assembly language programming skills and I want to code it again in FASM. First "quest" is to write the program wich get coordinates of point - let`s say - point A=(x,y) and it tells which quarter this point belongs to. I wrote an algorithm and it works well, I guess but only for unsigned numbers. When I type x= -8 or y= -1
my apps behave the same as if it has unsigned numbers. I don`t know what is wrong. Here is my source code:
Code:
format ELF64 
extrn printf
extrn scanf
public main

section '.text'  executable
main:
    push rbp
    mov  rbp, rsp
       
    mov  rdi, msg_type_x
        xor  rax, rax
       call printf
 
    mov  rsi, point_x
   mov  edi, scan
      xor  rax, rax
       call scanf
  
    mov  rdi, msg_type_y
        xor  rax, rax
       call printf
 
    mov  rsi, point_y
   mov  edi, scan
      xor  rax, rax
       call scanf

      
    mov  rax, [point_x]
 mov  rbx, [point_y]
 
    push rax
    push rbx
    call whereItIs
      pop  rbx
    pop  rax
    
    leave
       ret

whereItIs:
   cmp  rax, 0
 jg   bottomOrtop
    jmp  leftSide
 bottomOrtop:
          cmp  rbx, 0
         jg   firstQuarter
           mov  rdi, quarterIV
         xor  rax, rax
               call printf
         jmp  theEnd
         firstQuarter:
                   mov  rdi, quarterI
                  xor  rax, rax
                       call printf
                 jmp  theEnd
 leftSide:
       cmp  rbx, 0
 jg   secondQuarter
  mov  rdi, quarterIII
        xor  rax, rax
       call printf
 jmp  theEnd
 secondQuarter:
          mov  rdi, quarterII
         xor  rax, rax
               call printf
         
 theEnd:
    ret

section '.data'  writeable
msg_type_x   db      "Please type coordinate x: ",0
msg_type_y      db      "Please type coordinate y: ",0
point_x         dq      0
scan               db      "%d",0
point_y             dq      0
quarterI   db      "This point belongs to I quarter",0Ah,0
quarterII  db      "This point belongs to II quarter",0Ah,0
quarterIII        db      "This point belongs to III quarter",0Ah,0
quarterIV        db      "This point belongs to IV quarter",0Ah,0    

Compilation:
Code:
fasm code.asm
gcc   code.o -o code
    

I don`t thins so there is something bad with whereIsIt function. Maybe I`m wrong... Oh I`ve almost forgotten. I have to use GCC otherwise (using LD) i have to possible, stupid results. When i type this:
Code:
fasm code.asm
ld code.o -o code -lc
    

I have this message:
Code:
-bash: ./zadanie: No such file or directory
    

And output from strace:
Code:
execve("./zadanie", ["./zadanie"], [/* 46 vars */]) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f292e2f4000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(3, "strace: exec: No such file or dir"..., 40strace: exec: No such file or directory
) = 40
close(3)                                = 0
munmap(0x7f292e2f4000, 4096)            = 0
exit_group(1)                           = ?
    


And here you are the second,bad way. When i type this command:
Code:
fasm code.asm
ld code.o -o code -dynamic-linker /lib64/ld-linux.so.2 -lc
    

I have this message:
Code:
-bash: ./zadanie: Accessing a corrupted shared library
    

And strace`s output:
Code:
execve("./zadanie", ["./zadanie"], [/* 46 vars */]) = -1 ELIBBAD (Accessing a corrupted shared library)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5df893e000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(3, "strace: exec: Accessing a corrupt"..., 51strace: exec: Accessing a corrupted shared library
) = 51
close(3)                                = 0
munmap(0x7f5df893e000, 4096)            = 0
exit_group(1)                           = ?
    


I have no idea what is wrong with my program, i don`t know how to compile without using GCC (it adds to many syscall and makes program unnessesary bigger that it should be) moreover i don`t understand why calls from glibc are so odd. As far as I remember under 80x86 args were pushed onto stack, and there it looks like a putting values into registeres before syscall. I have to say that it is my first amd64 program in assembly language and I coded it using this link:
http://board.flatassembler.net/topic.php?t=8918

PS: I`m sorry for my english, I know it looks like a disaster Razz
[/code]
Post 21 Nov 2008, 07:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17342
Location: In your JS exploiting you and your system
revolution
You could try printing out the coordinates again after you have entered them just to see what scanf is returning to you after conversion. Maybe scanf does not return what you expect.
Post 21 Nov 2008, 11:01
View user's profile Send private message Visit poster's website Reply with quote
Doles



Joined: 21 Nov 2008
Posts: 4
Location: Wroclaw/Poland
Doles
Yes, you are right. Scanf() returns different number from this one which I expected. This is output from this "debug" version:
Please type coordinate x: -4
6295646Please type coordinate y: 94
Of course it is without any new line character so it looks very messy. But alright i guess this value "6295646" should be my "-4" number. It should be but it isn`t. I don`t really know maybe i shall write it in C, then use gcc with -S switch to look at the assembly code and recognize whole situation with comparison.
Post 21 Nov 2008, 13:25
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17342
Location: In your JS exploiting you and your system
revolution
There is nothing so powerful for debugging as a simple print function.
Post 21 Nov 2008, 14:53
View user's profile Send private message Visit poster's website Reply with quote
Doles



Joined: 21 Nov 2008
Posts: 4
Location: Wroclaw/Poland
Doles
I was googling, searching even researching in GAS code from basic C prgrams which compare number with 0 (just to see how the compiler can manage with JG or another conditional jump). Finally I`ve written this piece of code (yay it even works ! Razz) But my program has some strange behaviour when i type point (0,0). This is code:
Code:
format ELF64 
extrn printf
extrn scanf
public main

section '.text'  executable
main:
 push rbp
    mov  rbp, rsp

   sub  rsp, 16 

   mov  rdi, msg_type_x
        xor  rax, rax
       call printf
 
    sub  rbp, 4
 mov  rsi, rbp;point_x
       mov  edi, scan
      xor  eax, eax
       call scanf
  
    mov  rdi, msg_type_y
        xor  rax, rax
       call printf
 
    sub  rbp, 4
 mov  rsi, rbp;point_y
       mov  edi, scan
      xor  eax, eax
       call scanf

      add  rbp, 8
 mov  eax, [rbp-4]  ;[point_x]
       mov  ebx, [rbp-8]  ;[point_y]
       
    push rax
    push rbx
    call whereItIs
      pop  rbx
    pop  rax
    
    leave
       ret

whereItIs:

       cmp   eax, ebx
      jne   AxisXorY
      mov   rdi, inTheMiddle
      xor   rax, rax
      call  printf
        
 AxisXorY:
  
    cmp   eax, 0 ;test eax, eax
 je    onXaxis
       cmp   ebx, 0 ;test ebx, ebx
 jne   testCoordinates

 onYaxis:
  mov   rdi, Yaxis 
   xor   rax, rax
      call  printf
        jmp   theEnd

 onXaxis:
   mov   rdi, Xaxis
    xor   rax, rax
      call  printf
        jmp   theEnd


 testCoordinates:

   test  eax, eax 
     jns   bottomOrtop
   jmp  leftSide
 bottomOrtop:
          test  ebx, ebx
              jns   firstQuarter
          mov  rdi, quarterIV
         xor  rax, rax
               call printf
         jmp  theEnd
         firstQuarter:
                   mov  rdi, quarterI
                  xor  rax, rax
                       call printf
                 jmp  theEnd
 leftSide:
       test  ebx, ebx
      jns   secondQuarter
 mov  rdi, quarterIII
        xor  rax, rax
       call printf
 jmp  theEnd
 secondQuarter:
          mov  rdi, quarterII
         xor  rax, rax
               call printf
         
 theEnd:
    ret


section '.data'  writeable
msg_type_x       db      "Please type coordinate x: ",0
msg_type_y      db      "Please type coordinate y: ",0
point_x         dq      0
scan               db      "%d",0
point_y             dq      0
quarterI   db      "This point belongs to I quarter",0Ah,0
quarterII  db      "This point belongs to II quarter",0Ah,0
quarterIII        db      "This point belongs to III quarter",0Ah,0
quarterIV        db      "This point belongs to IV quarter",0Ah,0
Xaxis             db      "This point lies on X axis!",0Ah,0
Yaxis           db      "This point lies on Y axis!",0Ah,0
inTheMiddle     db      "This point lies int the middle",0Ah,0
    

And ok, there is an output message:
Code:
bartek@ipb121 ~/Kodziki/80x86_64/Zadanie1 $ ./zadanie_gcc 
Please type coordinate x: 0
Please type coordinate y: 0
This point lies int the middle
This point lies on Y axis!
    

For me every conditional branch looks very well, but something must be wrong so i can see this message. It strange why i should use 32bit variables to hold points, that use normal 64bit number. Does scanf() work good with 8-byte numbers ? BTW thanks for help Smile

***************EDIT***********
Ok I can see now my mistake. There has to be one more jump. Yeah, right there:
Code:
whereItIs:

        cmp   eax, ebx
      jne   AxisXorY
      mov   rdi, inTheMiddle
      xor   rax, rax
      call  printf
        jmp   theEnd ;<---- here you are Smile

 AxisXorY:    

Now all line of code works correctly. But still I don`t know how to link this app with C library under amd64...


Last edited by Doles on 21 Nov 2008, 16:08; edited 1 time in total
Post 21 Nov 2008, 15:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17342
Location: In your JS exploiting you and your system
revolution
I assume you need a "jmp theEnd" after each call to printf.
Post 21 Nov 2008, 16:02
View user's profile Send private message Visit poster's website Reply with quote
Doles



Joined: 21 Nov 2008
Posts: 4
Location: Wroclaw/Poland
Doles
Yeah, you were faster Smile
Post 21 Nov 2008, 16:09
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak
i know it's old, but the question must be answered...

Dude, you're using legacy datatypes. If in C you write printf("%x", 0xFFFFFFFFFFFFFFFF); you'll only get 8fs, not 16. add "l"... li or lx...
Post 03 Sep 2009, 19:45
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
mattst88



Joined: 12 May 2006
Posts: 260
Location: South Carolina
mattst88
Legacy datatypes?
Post 05 Sep 2009, 02:54
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.