flat assembler
Message board for the users of flat assembler.

Index > Programming Language Design > align directive

Author
Thread Post new topic Reply to topic
HopekForth



Joined: 13 Jul 2017
Posts: 8
Location: Poland
HopekForth 13 Jul 2017, 08:43
Good morning, everyone.

In his flat assembler 1.71 Programmer's Manual Tomek wrote about align directive:

Quote:
The align directive fills the bytes that had to be skipped to perform the alignment with the nop instructions


and later:

Quote:
If you need to fill the alignment area with some other values, you can combine align with virtual to get the size of alignment needed and then create the alignment yourself, like:

virtual
align 16
a = $ - $$
end virtual
db a dup 0

Today I found that the same can be done shorter:

db (- $) and $F dup 0

and you needn't know what virtual or $$ is Smile

You all can freely use my idea in your works.
Post 13 Jul 2017, 08:43
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 13 Jul 2017, 10:10
Keep in mind that this only works if $ has an absolute value (a known number), and this is not true in case of relocatable formats, like object files (COFF/ELF) or PE executables with fixups - for this reason internally implemented ALIGN directive was needed.
Post 13 Jul 2017, 10:10
View user's profile Send private message Visit poster's website Reply with quote
Sudoku



Joined: 05 Aug 2020
Posts: 1
Sudoku 05 Aug 2020, 06:01
Good day. First I want to thank HopekForth for the awesome formula db -$ and k dup 0 where k = n-1 and n is a power of 2! I can't count how many times it has saved my life Wink

Second, I have one suggestion for Tomek Grysztar on align directive in his flat assembler. It would be great if there would be an _optional_ second parameter for align directive, which would allow to specify the byte to fill the alignment area with other value than nop instruction code. Because it is optional parameter, all code will be compatible with this change of flat assembler.

For example, one could write:
align 16, 0
if one wants to write discussed example.

Tomek, is it possible to add this functionality to your flat assembler?
Post 05 Aug 2020, 06:01
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20416
Location: In your JS exploiting you and your system
revolution 05 Aug 2020, 06:07
Could that be extended to any arbitrary length repeating byte pattern?
Code:
align 16,0xaa,0x55 ;repeat aa,55,aa,55,... until filled    
Post 05 Aug 2020, 06:07
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 05 Aug 2020, 07:10
to Sodoku & HopekForth - names are traditionaly not translated (thay could go from 1 alphabet to another, but not more)
thour variant of macro is simple:
Code:
macro align pow*,filler:? { db (-$+$$) and (pow-1) dup filler }    

example of use:
Code:
db 1
align 4,$34
align 8
db 1     

If thou will be initialy pretty smart & wouldn`t use alignments others than power of 2 macro could fit one row.
for common use will be needed one more line:
Code:
assert bsf pow = bsr pow    


revolution, on thour level of assembly skill such things are easier manualy.
(advantage of macro implementation is unsugnificant in comparison to cost of preprocessor resources).
by the way thou skilled as nobody other in patching of fasm core.

And one more: in case of $AA, $55 assumed that they fit $AA even byte but $55 odd byte. So we could see that in general case power of alignment & filling pattern are not enought parameters (needed information how pattern should interfere with particular alignment), but if we add more parameters they wouldn`t be intuitive.

So, cuurrent (in fasm core) alignment implementation is the best case.
Post 05 Aug 2020, 07:10
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20416
Location: In your JS exploiting you and your system
revolution 05 Aug 2020, 07:15
ProMiNick: Please note the comment from Tomasz about why using db can be a problem.

https://board.flatassembler.net/topic.php?p=197948#197948
Tomasz Grysztar wrote:
Keep in mind that this only works if $ has an absolute value (a known number), and this is not true in case of relocatable formats, like object files (COFF/ELF) or PE executables with fixups - for this reason internally implemented ALIGN directive was needed.
Post 05 Aug 2020, 07:15
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 05 Aug 2020, 07:52
this magic (-$+$$) resolve problem.
Thou were not paying attention. Smile
(I resolved it in past when I was needed to make libraries for kolibri OS, they are in COFF format - so solution is tested)
Code:
; Copyright (C) KolibriOS team 2008-2020. All rights reserved.
format  MS COFF
;-------------------------------------------------
; INFO
;-------------------------------------------------
libname         equ 'messagebox'
LIB_VERSION     equ 1
;-------------------------------------------------
; INCLUDES
;-------------------------------------------------
include 'kolibria.inc'
;include 'C:\fasmpack\INCLUDES\OS_SPECS\KOLIBRI\EQUATES/kernel.inc'
;include 'C:\fasmpack\INCLUDES\OS_SPECS\KOLIBRI\EQUATES/syscalls.inc'
;include 'C:\fasmpack\INCLUDES\OS_SPECS\KOLIBRI\EQUATES/keys.inc'
;include 'C:\Kolibrios.org\programs\macros.inc'
include 'mbxdata.inc'

;ID_BTN_SYS_CLOSE            =  1
;ID_BTN_USER_FIRST        =  3
MB_MAX_BTN_COUNT        =  8
MB_BTN_HEIGHT           = 20
BORDER_HEIGHT           =  5
CHAR_WIDTH              =  6
MBX_VERT_SPACING        =  5
MBX_HORZ_SPACING_1      =  5
MBX_HORZ_SPACING_2      = 10
MBX_HORZ_SPACING_3      = 15
;MBX_CAPTION_OFFSET          =  2
;-------------------------------------------------
; CODE
;-------------------------------------------------
section '.flat' code readable align 16
mbx_thread_proc:
        mcall   SF_STYLE_SETTINGS,SSF_GET_COLORS,sc,sizeof.system_colors
        mcall   SF_SET_EVENTS_MASK,EVM_BUTTON or EVM_KEY or EVM_REDRAW

  ;-- clear id pressed button ---
        mov     eax,[mb_text]
        mov     eax,dword[eax]
        add     eax,ID_BTN_USER_FIRST
        dec     eax
        mov     [mb_focused_button],eax

  stdcall MsgBoxReInit,[mb_text]

  call do_redraw
still:
        sub     esp,4
        mcall   SF_WAIT_EVENT
        movzx   ecx,al
        jmp     [event_handlers+4*ecx]
event_handlers  dd 0,do_redraw,key,button
;-------------------------------------------------
key:
        mcall   SF_GET_KEY
        ror     eax,8
        cmp     ah,SCAN_CODE_RETURN
        jne     @F
        mov     eax,[mb_focused_button]
        jmp     close
      @@:
        cmp     al,ASCII_KEY_LEFT
        jne     .check_next
        cmp     [mb_focused_button],ID_BTN_USER_FIRST
  jg @f
        mov     eax,[mb_button_count]
        add     [mb_focused_button],eax
  @@:
        dec     [mb_focused_button]
        jmp     MsgBoxDrawAllBtns
        ;jmp     still

      .check_next:
        cmp     ah,SCAN_CODE_TAB
        je      .focus_next_btn
        cmp     al,ASCII_KEY_RIGHT
        je      .focus_next_btn
        retn

      .focus_next_btn:
        mov     eax,[mb_button_count]
        add     eax,ID_BTN_USER_FIRST
        cmp     [mb_focused_button],eax
        jne     @F
        retn
      @@:
        inc     [mb_focused_button]
        cmp     [mb_focused_button],eax
        jl      @f
        mov     [mb_focused_button],ID_BTN_USER_FIRST
      @@:
        jmp    MsgBoxDrawAllBtns
        ;jmp     still
;-------------------------------------------------
button:
        mcall   SF_GET_BUTTON
        test    al,al
        jz      .LMBclick
        retn

      .LMBclick:
        shr     eax,8
        cmp     eax,ID_BTN_USER_FIRST
        jge     close
        cmp     eax,ID_BTN_SYS_CLOSE
        je      @F
        retn
      @@:
;.exit:
        mov     eax,ID_BTN_USER_FIRST
        dec     eax
close:
        sub     eax,ID_BTN_USER_FIRST-1
        mov     ebx,[mb_text]
        mov     [ebx],eax

  ;*** call msgbox functions ***
        cmp     dword[mb_funct],0
        jz      @F
        test    eax,eax
        jz      @F
        dec     eax
        shl     eax,2
        add     eax,dword[mb_funct]
        cmp     dword[eax],0
        jz      @F
        call    dword[eax]
      @@:
        mcall   SF_TERMINATE_PROCESS
;-------------------------------------------------
  do_redraw:
        mcall   SF_REDRAW,SSF_BEGIN_DRAW

        mov     edx,[sc.work]
        or      edx,CW_CAPTION or CW_CLIENTRECTCOORDS or CW_SKINED
        mov     edi,[mb_text]
        add     edi,MBX_CAPTION_OFFSET ;Caption
        mcall   SF_CREATE_WINDOW,dword[mb_width_left],dword[mb_height_top]

        mcall   SF_THREAD_INFO,mbx_thread_info,-1
        mov     eax,dword[mbx_thread_info.client_box.width]

        sub     eax,[btn_width]
        shr     eax,1
        add     eax,MBX_HORZ_SPACING_1
        mov     [ot_left],ax

        mpack   ebx,MBX_HORZ_SPACING_1,MBX_VERT_SPACING
        mov     ecx,[sc.work_text]
        mov     edx,[txtMsg]

      @@:
        mov     edi,edx
        push    ecx
        call    GetStrLength
        call    GetStrLineLength
        mov     esi,ecx
        sub     esi,1
        pop     ecx
        jz      @F
        mcall   SF_DRAW_TEXT
        add     edx,esi
        cmp     byte[edx],0
        je      @F
        inc     edx

        add     ebx,10 ; move <--y-->
        jmp     @B
      @@:
        call    MsgBoxDrawAllBtns
        mcall   SF_REDRAW,SSF_END_DRAW
        retn
;-------------------------------------------------
MsgBoxDrawAllBtns:

  ; Buttons ...
        push    esi
        mov     esi,txtBut
        mov     edx,ID_BTN_USER_FIRST

        mov     ebx,dword[ot_top_left]
        add     ebx,MBX_VERT_SPACING
        jmp     .left_coor_calculated
      .next_button:
        inc     edx                    ; next button ID(edx)

        imul    ecx,CHAR_WIDTH         ; calculate new topleft coord (ebx)
        add     ecx,MBX_HORZ_SPACING_3 ; taking in account button caption length (ecx)
        shl     ecx,16                 ; calculated at previous iteration step
        add     ebx,ecx

      .left_coor_calculated:
        mov     edi,[esi]              ; get ptr(edi) to button caption of current array item(esi)
        call    GetStrLength
        sub     ecx,1
        jz      .last_button_done
        call    MsgBoxDrawButton
        add     esi,4                  ; look for next array item (esi) if any
        cmp     esi,endBut
        jb      .next_button

      .last_button_done:
        pop     esi
        retn

;input:
; ecx = button id
align 4
MsgBoxDrawButton:
; [in/out/unchanged]    ebx:button caption topleft coord
; [in/out/unchanged]    ecx:button caption length
; [in/out/unchanged]    edx:button id
; [unchanged too]       esi,edi,ebp
        push    esi
        push    edx
        push    ecx
        push    ebx

        mov     esi,[sc.work_button]
        cmp     edx,[mb_focused_button]
        jne     @F
        mov     esi,[sc.work_button_text]
      @@:
        imul    ecx,CHAR_WIDTH
        add     ecx,MBX_HORZ_SPACING_2
        mov     bx,cx
        sub     ebx,MBX_HORZ_SPACING_1 shl 16
        mov     ecx,[esp]
        shl     ecx,16
        add     ecx,(-MBX_VERT_SPACING)shl 16 + MB_BTN_HEIGHT
        mcall   SF_DEFINE_BUTTON

        mov     ecx,[sc.work_button_text]
        cmp     esi,ecx
        jne     @F
        mov     ecx,[sc.work_button]
      @@:
        pop     ebx
        mcall   SF_DRAW_TEXT,,,edi,[esp]
        pop     ecx
        pop     edx
        pop     esi
        retn

sizeof.RET      = 4
sizeof.ARG      = 4
sizeof.PUSHAD   = 8*4
;-------------------------------------------------
MsgBoxReInit:
        pushad
        add     esp,sizeof.PUSHAD+sizeof.RET
        pop     edi
        sub     esp,sizeof.PUSHAD+sizeof.RET+sizeof.ARG
        mov     [mb_text],edi
        add     edi,MBX_CAPTION_OFFSET
        call    GetStrLength
        add     edi,ecx
        mov     [txtMsg],edi

  ;--- go to first button text --- buttons 1...MB_MAX_BUT
        mov     ebx,txtBut
        mov     ecx,MB_MAX_BTN_COUNT
  @@:

    ;call strlen
        push    ecx
        call    GetStrLength
        add     edi,ecx
        pop     ecx
        mov     dword[ebx],edi
        cmp     byte[edi],0
        je      @F
        add     ebx,4
        loop    @B
      @@:

  ;--- calc button top ---
        mov     eax,1
        mov     ebx,[txtMsg]
      @@:
        inc     ebx
        cmp     byte[ebx],0
        je      @F
        cmp     byte[ebx],$D
        jne     @B
        inc     eax
        jmp     @B
      @@:
        imul    eax,10
        add     eax,2*MBX_VERT_SPACING
        mov     [ot_top],ax

  ;--- calc window height ---
        add     eax,MBX_VERT_SPACING + MB_BTN_HEIGHT + BORDER_HEIGHT
        mov     [mb_height],ax
        mcall   SF_STYLE_SETTINGS,SSF_GET_SKIN_HEIGHT ;skin height
        add     [mb_height],ax

  ;--- calc window top ---
        mcall   SF_GET_SCREEN_SIZE
        sub     ax,[mb_height]
        shr     ax,1
        mov     [mb_top],ax
  ;--- and window left
        shr     eax,16
        sub     ax,[mb_width]
        shr     ax,1
        mov     [mb_left],ax

  ;--- calc button width ---
        xor     ebx,ebx
        xor     ecx,ecx
        mov     edi,[txtBut]
        and     [mb_button_count],0
      @@:
        cmp byte[edi],0
        je      @F
        inc     ecx
        push    ecx
        call    GetStrLength
        add     edi,ecx
        inc     [mb_button_count]
        dec     ecx
        add     ebx,ecx
        pop     ecx
        jmp     @B
      @@:
        imul    ebx,CHAR_WIDTH
        imul    ecx,MBX_HORZ_SPACING_3
        lea     ebx,[ebx+ecx+MBX_HORZ_SPACING_2-MBX_HORZ_SPACING_3]
        mov     [btn_width],ebx
        popad
  ret 4
;-------------------------------------------------
MsgBoxCreate:
        pushad  ; more better trash everyreg and caller care pushad
        add     esp,sizeof.PUSHAD+sizeof.RET
        pop     [mb_text]
        sub     esp,sizeof.PUSHAD+sizeof.RET+sizeof.ARG
        mcall   SF_CREATE_THREAD,1,mbx_thread_proc,[esp+sizeof.PUSHAD+sizeof.RET+sizeof.ARG]
        popad
  ret 8
;-------------------------------------------------
MsgBoxSetFunctions:
        pop     eax
        pop     [mb_funct]
        jmp     eax
;-------------------------------------------------
GetStrLength:
; [in]          edi:string pointer
; [out]         ecx:string length(with trailing 0)
; [unchanged]   ebx, edx, esi, edi, ebp, esp
        or      ecx, -1
        xor     eax, eax
        cld
        repne scasb
        not     ecx
        sub     edi,ecx
        retn
;-------------------------------------------------
GetStrLineLength:
; [in]          edi:string pointer
; [in]          ecx:string length(with trailing 0)
; [out]         ecx:string line length(with trailing 0 or $D)
; [unchanged]   ebx, edx, esi, edi, ebp, esp
        push    ecx
        mov     al,$D
        repne scasb
        sub     [esp],ecx
        pop     ecx
        sub     edi,ecx
        retn
;-------------------------------------------------
; EXPORT
;-------------------------------------------------
export \
        MsgBoxCreate,           'mb_create',\
        MsgBoxReInit,           'mb_reinit',\
        MsgBoxSetFunctions,     'mb_setfunctions'
;-------------------------------------------------
; INITIALIZED DATA                         
;-------------------------------------------------
  ;--- à §¬¥àë ­  íªà ­¥ ®ª­  á®®¡é¥­¨ï ---
  mb_width_left:
  mb_width              dw 300
  mb_left               dw 0
  mb_height_top:
  mb_height             dw 50
  mb_top                dw 0
  mb_focused_button     dd ID_BTN_USER_FIRST ;ª­®¯ª  ¢ 䮪ãᥠ ãç¥â®¬ MB_FIRST_BUT_ID)
  mb_button_count       dd 1 ;ç¨á«® ¢á¥å ª­®¯®ª á®®¡é¥­¨ï

  txtMsg                dd ? ;㪠§ â¥«ì ­  ­ ç «® ⥪áâ  á®®¡é¥­¨ï
  txtBut                rd MB_MAX_BTN_COUNT ;㪠§ â¥«ì ­  ­ ç «® ⥪áâ  ¯®¤¯¨á¥© ª­®¯®ª
  endBut:
  ot_top_left:
  ot_top                dw ? ;®âáâ㯠ᢥàåã (¤«ï à¨á®¢ ­¨ï ª­®¯®ª)
  ot_left               dw ? ;®âáâ㯠᫥¢  (¤«ï à¨á®¢ ­¨ï ª­®¯®ª)
  btn_width             dd ? ;summary width of all buttons including spaces between them
;--------------------------------------------------
  mb_text               dd ? ;msgbox_1 ;㪠§ â¥«ì ¤ ­­ë¥ ¤«ï á®®¡é¥­¨ï (ª®â®àë ¯¥à¥¤ îâìáï ®ª­ã)
  mb_funct              dd ? ;pointer to functions
  sc                    system_colors
  mbx_thread_info       process_information ;㪠§ â¥«ì ­  áâàãªâãàã process_information த¨â¥«ì᪮£® ®ª­       


thou can see align present there, and all successfuly compiled, and that lib even used in other demo (but my version may be different than that presented in OS).
Post 05 Aug 2020, 07:52
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20416
Location: In your JS exploiting you and your system
revolution 05 Aug 2020, 08:25
Very good. But I see it using the normal align, right? Not your db version.

BTW: You can use ($$-$) or (-$+$$) for the same result.
Post 05 Aug 2020, 08:25
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20416
Location: In your JS exploiting you and your system
revolution 05 Aug 2020, 08:40
I notice this difference when using (-$+$$):
Code:
virtual at 7
align 16
display $+'0'
end virtual

virtual at 7
db (-$) and 15 dup 0
display $+'0'
end virtual

virtual at 7
db (-$+$$) and 15 dup 0
display $+'0'
end virtual    
Output:
Code:
@@7    
Expected output:
Code:
@@@    
Post 05 Aug 2020, 08:40
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 05 Aug 2020, 08:53
Oh, it was not related with COFFs there all operated properly.
in case of COFFs align directive resolve variable base, but in case of variable base of virtual blocks - not.
my struct realization supposed aligned members and when they passed as locals on stack they raised error similar to
Code:
virtual at esp
align 4
end virtual    

so because of that I redefine align.
Post 05 Aug 2020, 08:53
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20416
Location: In your JS exploiting you and your system
revolution 05 Aug 2020, 09:23
I get the same result with org.
Code:
org 7
align 16
display $+'0'

org 7
db (-$) and 15 dup 0
display $+'0'

org 7
db (-$+$$) and 15 dup 0
display $+'0'    
Post 05 Aug 2020, 09:23
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.