flat assembler
Message board for the users of flat assembler.
Index
> Linux > Signed number with scanf under Gentoo 80x86_64 |
Author |
|
Doles 21 Nov 2008, 07:34
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 [/code] |
|||
21 Nov 2008, 07:34 |
|
Doles 21 Nov 2008, 13:25
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. |
|||
21 Nov 2008, 13:25 |
|
revolution 21 Nov 2008, 14:53
There is nothing so powerful for debugging as a simple print function.
|
|||
21 Nov 2008, 14:53 |
|
Doles 21 Nov 2008, 15:57
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 ! ) 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 ***************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 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 |
|||
21 Nov 2008, 15:57 |
|
revolution 21 Nov 2008, 16:02
I assume you need a "jmp theEnd" after each call to printf.
|
|||
21 Nov 2008, 16:02 |
|
Doles 21 Nov 2008, 16:09
Yeah, you were faster
|
|||
21 Nov 2008, 16:09 |
|
kohlrak 03 Sep 2009, 19:45
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... |
|||
03 Sep 2009, 19:45 |
|
mattst88 05 Sep 2009, 02:54
Legacy datatypes?
|
|||
05 Sep 2009, 02:54 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.