flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
revolution 31 May 2010, 22:57
denat: You have to state the format in the source before you put any instructions or code.
Code: format elf Code: rb 128 ;reserve 128 bytes |
|||
![]() |
|
LocoDelAssembly 31 May 2010, 23:21
There are more errors actually (for instance "global" should be "public"). It is worth noting that fasm is not just a nasm clone written in Assembly instead of C, it is true that them share some things in common at the syntax level, but them are not 100% compatible with each other.
I found the author's site and example so I'm giving here the 64-bit version with fasm: Code: ; This is a modification of Jeff Duntemann example to work in 64-bit and be compilable with fasm ; Build using these commands: ; fasm charsin.asm ; gcc charsin.o -o charsin ;=== Comment from Original author follows: ; Source name : CHARSIN.ASM ; Executable name : CHARSIN ; Version : 2.0 ; Created date : 11/21/1999 ; Last update : 5/28/2009 ; Author : Jeff Duntemann ; Description : A character input demo for Linux, using NASM 2.05, ; incorporating calls to both fgets() and scanf(). ; ; Build using these commands: ; nasm -f elf -g -F stabs charsin.asm ; gcc charsin.o -o charsin ; format elf64 section '.data' ;[SECTION .data] ; Section containing initialised data SPrompt db 'Enter string data, followed by Enter: ',0 IPrompt db 'Enter an integer value, followed by Enter: ',0 IFormat db '%d',0 SShow db 'The string you entered was: %s',10,0 IShow db 'The integer value you entered was: %5d',10,0 section '.bss' writable ;[SECTION .bss] ; Section containing uninitialized data IntVal rd 1 ;resd 1 ; Reserve an uninitialized double word InString rb 128 ;resb 128 ; Reserve 128 bytes for string entry buffer section '.text' executable ;[SECTION .text] ; Section containing code extrn stdin ;extern stdin ; Standard file variable for input extrn fgets ;extern fgets extrn printf ;extern printf extrn scanf ;extern scanf public main ;global main ; Required so linker can find entry point main: push rbp ;ebp ; Set up stack frame for debugger mov rbp, rsp ;ebp,esp ; === The saving was innecesary as them are not written (and in 64-bit you have to preserve a different set anyway) ;push ebx ; Program must preserve ebp, ebx, esi, & edi ;push esi ;push edi ;;; Everything before this is boilerplate; use it for all ordinary apps! ; First, an example of safely limited string input using fgets: mov rdi, SPrompt ;push SPrompt ; Push address of the prompt string xor eax, eax ;[added instruction] AL specifies the number of vector registers used for variadic functions. (Got segfault without this) call printf ; Display it ;add esp,4 ; Stack cleanup for 1 parm mov rdx, [stdin] ;push dword [stdin] ; Push file handle for standard input mov esi, 72 ;push 72 ; Accept no more than 72 chars from keybd ;;; (NOTE: The instruction automatically clears RSI[63:32]) mov rdi, InString ;push InString ; Push address of buffer for entered chars call fgets ; Call fgets ;add esp,12 ; Stack cleanup: 3 parms X 4 bytes = 12 mov rsi, InString ;push InString ; Push address of entered string data buffer mov rdi, SShow ;push SShow ; Push address of the string display prompt xor eax, eax ;[added instruction] AL specifies the number of vector registers used for variadic functions. (Got segfault without this) call printf ; Display it ;add esp,8 ; Stack cleanup: 2 parms X 4 bytes = 8 ; Next, use scanf() to enter numeric data: mov rdi, IPrompt ;push IPrompt ; Push address of the integer input prompt xor eax, eax;[added instruction] AL specifies the number of vector registers used for variadic functions. (Got segfault without this) call printf ; Display it ;add esp,4 ; Stack cleanup for 1 parm ;Code that was used to check Ubuntu behavior ;xor eax, eax ;mov qword [IntVal], rax mov rsi, IntVal ;push IntVal ; Push the address of the integer buffer mov rdi, IFormat ;push IFormat ; Push the address of the integer format string xor eax, eax;[added instruction] AL specifies the number of vector registers used for variadic functions. (Got segfault without this) call scanf ; Call scanf to enter numeric data ; (NOTE: At least in Ubuntu 9.10, scanf is reading the number as a "long long" and then returning the lower half) ;add esp,8 ; Stack cleanup: 2 parms X 4 bytes = 8 ;Code that was used to check Ubuntu behavior ;cmp dword [IntVal+4], 0 ;je @f ;int3 ;@@: mov esi, [IntVal] ;push dword [IntVal] ; Push integer value to display mov rdi, IShow ;push IShow ; Push base string xor eax, eax;[added instruction] AL specifies the number of vector registers used for variadic functions. (Got segfault without this) call printf ; Call printf to convert & display the integer ;add esp,8 ; Stack cleanup: 2 parms X 4 bytes = 8 ;;; Everything after this is boilerplate; use it for all ordinary apps! ;=== Were not saved (see prolog comment) ;pop edi ; Restore saved registers ;pop esi ;pop ebx mov rsp, rbp ;esp,ebp ; Destroy stack frame before returning pop rbp ;ebp ret ; Return control to Linux ; === The original author seems to have repeated the data and bss sections using uncapitalized names. ; === I'll proceed commenting the remaining of the code for being not useful ;[SECTION .data] ; Section containing initialised data ; ;sprompt db 'Enter string data, followed by Enter: ',0 ;iprompt db 'Enter an integer value, followed by Enter: ',0 ;iformat db '%d',0 ;sshow db 'The string you entered was: %s',10,0 ;ishow db 'The integer value you entered was: %5d',10,0 ; ;[SECTION .bss] ; Section containing uninitialized data ; ;intval resd 1 ; Reserve an uninitialized double word ;instring resb 128 ; Reserve 128 bytes for string entry buffer Code: loco@athlon64:~$ fasm charsin.asm flat assembler version 1.69.11 (16384 kilobytes memory) 1 passes, 1487 bytes. loco@athlon64:~$ gcc charsin.o -o charsin loco@athlon64:~$ ./charsin Enter string data, followed by Enter: Hello World! :D The string you entered was: Hello World! :D Enter an integer value, followed by Enter: 31052010 The integer value you entered was: 31052010 loco@athlon64:~$ Underscore decoration was not needed, however, I'm not sure if that is always the case or if it is my libs that are exporting the functions twice to make them reachable in both ways. |
|||
![]() |
|
donn 01 Jun 2010, 03:31
So awesome, you helped with this step 100%. Read through the 64-version example, things like the xor eax, eax I probably wouldn't have been able to come up with, with even the segfault error displaying. I'm going to put the knowledge you both gave me to good use, keep figuring things out, and getting the basis down more. The example ran beautifully, cool, great that you know these things.
That was very helpful, and very fast too, Denat |
|||
![]() |
|
LocoDelAssembly 01 Jun 2010, 05:06
For more information about the calling convention see this doc (I've to read it myself when porting Jeff's code): http://www.x86-64.org/documentation/abi.pdf
Note that only AL needs to be set to zero, but I thought that clearing the entire RAX register (xor eax, eax also clears RAX[63:32]) may be handled by the processor more easily (the size of "mov al, 0" is the same that the size of "xor eax, eax", two). |
|||
![]() |
|
donn 06 Jun 2010, 23:42
Hey, seems page 21 is very helpful, shows the register behaviors in a table. With rbx, rsp, rbp and r12-r15 being saved and keeping their values once the global function is called. But rbp can be used for the stack frame by pushing it, Why is rsp said to be preserved if it is updated once the stack decreases, maybe because the function doesn't interfere with its role with things we don't need? It also shows the argument order registers, rdi rsi rdx, very cool. It seems xmm0-xmm1 can return floating point, where xmm2-xmm7 pass only (after xmm0-xmm1 are used), but is page 23 saying otherwise? it goes xmm0, then 1, then ymm2 then xmm3, skipping xmm2 also. This can probably be tested. I think it says for AVX like usage, ymm and xmm are interchangeable, they can have the same value, only one can be used at a time. That makes sense, then. Solid, LocoDelAssembly, good night.
Denat |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.