News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

A very simple GAS example

Started by Vortex, December 18, 2005, 04:15:53 PM

Previous topic - Next topic

Vortex

For those who are interested, here is a simple GAS example.

.intel_syntax noprefix
.global _start

.data
.extern _MessageBoxA@16
.extern _ExitProcess@4

.set MessageBox,_MessageBoxA@16 /* .set = EQU */
.set ExitProcess,_ExitProcess@4

message:
.ascii "Hello world!"           /* define NULL terminated string */
.byte 0
caption:
.ascii "Message box"
.byte 0

.text
_start:
    pushd   0                   /* push DOUBLE word */
    push    OFFSET caption
    push    OFFSET message
    pushd   0
    call    MessageBox
    pushd   0
    call    ExitProcess


Building the project : ( I am using the GNU tools coming with FreeBASIC package )
C:\Freebasic\bin\win32\as -o %1.o %1.asm
C:\Freebasic\bin\win32\ld -e_start -subsystem windows -Lc:\masm32\lib -o %1.exe %1.o --library=user32  --library=kernel32 -s

[attachment deleted by admin]

hutch--

Vortex,

Thanks for the demo, I wonder if there is another way to get hold of "AS" ? I remember climbing through the GNU site and could not find it.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Vortex

Hi Hutch,

All the information what I found to use the GNU assembler as.exe :

Manual for as.exe :

http://www.gnu.org/software/binutils/manual/gas-2.9.1/html_mono/as.html#SEC2

A nice CHM documentation :

ftp://ftp.berlios.de/pub/htmlhelp/as-2.15.chm

GregL

Well, at least it supports Intel syntax now, it didn't used to. I couldn't stand looking at gas code before, this is better.

Vortex

Hi Greg,

Yes, you are right. One feels really very uncomfortable with the  AT&T syntax.

MusicalMike

The only reason to use gas is if you are on a linux machine, and FASM does the job better.

hutch--

Looks like a nice low level tool. With thanks to Vortex for the original example, here is a quick play with GAS using the Intel syntax.


/* -------------------------------------------------------------- */

    .intel_syntax noprefix
    .global _entry_point

    .macro msgbox arg1,arg2,arg3,arg4
      push \arg4                              /* push DOUBLE word */
      push OFFSET \arg3
      push OFFSET \arg2
      push \arg1
      call MessageBox
    .endm

    .macro quit
      push 0
      call ExitProcess
    .endm

  .data
    .extern _MessageBoxA@16
    .extern _ExitProcess@4

    .set MessageBox,_MessageBoxA@16
    .set ExitProcess,_ExitProcess@4

.text

    // ----------------------------------------
    // howdy, I am a leading C++ commented text
    // ----------------------------------------

    message: .ascii "Its a GAS\x00"     /* ZERO terminated string */
    caption: .ascii "Hey man !\x00"

/* -------------------------------------------------------------- */

_entry_point:

    .data
      buffer: .ascii "                    "
    .text

    push ebx

    mov ecx, OFFSET message
    mov edx, OFFSET buffer
    xor ebx, ebx
    call szcopy

    pop ebx

    msgbox 0,buffer,caption,0

    quit

/* -------------------------------------------------------------- */

  szcopy:
    mov al, BYTE PTR [ecx+ebx]
    mov BYTE PTR [edx+ebx], al
    add ebx, 1
    test al, al
    jnz szcopy

    ret

/* -------------------------------------------------------------- */
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

GregL

I had a play with it too. It's not that bad. Once you get the hang of it, it works pretty well.


.intel_syntax noprefix
.arch pentium
.global _start

GetStdHandle = _GetStdHandle@4
lstrlen      = _lstrlenA@4
WriteConsole = _WriteConsoleA@20
ExitProcess  = _ExitProcess@4

NULL              =   0
STD_OUTPUT_HANDLE = -11

.data

    szTitle: .asciz "\nGNU Assembler Example\n\n"
    szMsg:   .asciz " Hello from GAS!\n\n"

.bss

    hStdOut:      .long 0
   
    dwNumWritten: .long 0

    dwNumToWrite: .long 0

    // szBuffer:  .space 255, 0

.text

_start:

    push    STD_OUTPUT_HANDLE
    call    GetStdHandle
    mov     hStdOut, eax
   
    push    OFFSET szTitle
    call    lstrlen
    mov     dwNumToWrite, eax

    push    NULL
    push    OFFSET dwNumWritten
    push    dwNumToWrite
    push    OFFSET szTitle
    push    hStdOut
    call    WriteConsole
   
    push    OFFSET szMsg
    call    lstrlen
    mov     dwNumToWrite, eax
   
    push    NULL
    push    OFFSET dwNumWritten
    push    dwNumToWrite
    push    OFFSET szMsg
    push    hStdOut
    call    WriteConsole

    push    0
    call    ExitProcess
   
.end


hutch--

Has some useful directives as well.


/* -------------------------------------------------------------- */

    .intel_syntax noprefix
    .global _entry_point

    .macro msgbox arg1,arg2,arg3,arg4
      push \arg4                              /* push DOUBLE word */
      push OFFSET \arg3
      push OFFSET \arg2
      push \arg1
      call MessageBox
    .endm

    .macro exit
      push 0
      call ExitProcess
    .endm

  .data
    .extern _MessageBoxA@16
    .extern _ExitProcess@4

    .set MessageBox,_MessageBoxA@16
    .set ExitProcess,_ExitProcess@4

    .set MB_OK,                 0x00
    .set MB_OKCANCEL,           0x01
    .set MB_ABORTRETRYIGNORE,   0x02
    .set MB_YESNOCANCEL,        0x03
    .set MB_YESNO,              0x04
    .set MB_RETRYCANCEL,        0x05
    .set MB_ICONHAND,           0x10
    .set MB_ICONQUESTION,       0x20
    .set MB_ICONEXCLAMATION,    0x30
    .set MB_ICONASTERISK,       0x40

.text

    // ----------------------------------------
    // howdy, I am a leading C++ commented text
    // ----------------------------------------

    message: .ascii "Its a GAS\nIts a GAS\x00"     /* ZERO terminated string */
    caption: .ascii "Hey man !\x00"

/* -------------------------------------------------------------- */

_entry_point:

    .data
      buffer: .ascii "                              "
    .text

    push OFFSET buffer
    push OFFSET message
    call szcopy

    msgbox 0,buffer,caption,MB_OK | MB_ICONASTERISK

    exit

/* -------------------------------------------------------------- */

  .align 8
  szcopy:

    mov ecx, [esp+4]
    mov edx, [esp+8]

    push ebx
    xor ebx, ebx

  cpy:
  .rept 3
    mov al, [ecx+ebx]
    mov [edx+ebx], al
    add ebx, 0x01
    test al, al
    jz cpout
  .endr

    mov al, [ecx+ebx]
    mov [edx+ebx], al
    add ebx, 0x01
    test al, al
    jnz cpy

  cpout:

    pop ebx

    ret 8

/* -------------------------------------------------------------- */
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

It also does address substitution with .long data types.


  // -----------------------
  // zero terminated strings
  // -----------------------
    message: .ascii "Its a GAS\nIts a GAS\x00"     /* ZERO terminated string */
    caption: .ascii "Hey man !\x00"

  // -----------------------------------
  // pointers to zero terminated strings
  // -----------------------------------
    pmsg: .long message
    pttl: .long caption


On the fly .DATA seems to work fine as well.


    .data
      buffer: .fill 128         /* 128 byte buffer */
      pbuf: .long buffer        /* pointer to buffer */
    .text
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

Here is a near complete set of include files for AS.

You need to use double backslashes in the paths as follows.

    .include "h:\\gas\\include\\user32.in"
    .include "h:\\gas\\include\\kernel32.in"


[attachment deleted by admin]
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

drhowarddrfine

QuoteThe only reason to use gas is if you are on a linux machine, and FASM does the job better.
Well, it is the assembler for GCC so it's probably pretty good.  I started tinkering with it because I run FreeBSD but got sidetracked with some C stuff.  There is a whole tutorial on AS on the FreeBSD sites developers site and the Whizkid has one, too.  (They were both written by himi).  What little I did shows me that it is no more difficult using as/gas than switching between any two similar languages. 

GregL

An example using msvcrt.dll.


.intel_syntax noprefix
.arch pentium
.global _start

GetStdHandle = _GetStdHandle@4
lstrlen      = _lstrlenA@4
WriteConsole = _WriteConsoleA@20
ExitProcess  = _ExitProcess@4
sprintf      = _sprintf
_getch       = __getch

NULL              =   0
STD_OUTPUT_HANDLE = -11

.macro exit rv
    push    \rv
    call    ExitProcess
.endm

.macro printsz szStr
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle
    mov     hStdOut, eax
    push    OFFSET \szStr
    call    lstrlen
    mov     dwNumToWrite, eax
    push    NULL
    push    OFFSET dwNumWritten
    push    dwNumToWrite
    push    OFFSET \szStr
    push    hStdOut
    call    WriteConsole   
.endm

.macro getPi Pi
    finit
    fldpi
    fstp    QWORD PTR \Pi
.endm   

.data

    szTitle: .asciz "\nGNU Assembler Example\n\n"
    szMsg:   .asciz " It's a GAS!\n\n"
    szFmt:   .asciz " Pi = %.12lf\n\n"
    szPAK:   .asciz "Press any key to exit..."
    szLf:    .asciz "\n"

.bss

    hStdOut:      .long 0
   
    dwNumWritten: .long 0

    dwNumToWrite: .long 0
   
    dblPi:        .double 0.0

    szBuffer:     .space 32, 0

.text

_start:

    printsz szTitle
    printsz szMsg
   
    getPi   dblPi
   
    push    [dblPi+4]
    push    [dblPi+0]
    push    OFFSET szFmt
    push    OFFSET szBuffer
    call    sprintf
    add     esp, 4 * 4  /*_cdecl*/
   
    printsz szBuffer

    printsz szPAK
    call    _getch
    cmp     eax, 0
    je      again
    cmp     eax, 0xE0
    je      again
    jmp     done
  again:
    call    _getch
  done: 
    printsz szLf
   
    exit    0
   
.end

Vortex

Hutch, Greg,

Thanks for the examples :U

Vortex

Hello world example linked with PoLink to reduce the size of the final executable to 1536 bytes.

[attachment deleted by admin]