fasm g

Тема в разделе "FASM", создана пользователем f13nd, 18 ноя 2018.

  1. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    Решил тут на днях поплотней взяться за новый фасм и определиться 'г' - 'гармония' или нечто иное? Соорудил ассемблер для Renesas SH-2A под новый фасм. Все получилось и даже работает.
    Фасм теперь позиционируется как 'assembler engine' - движок, а не ассемблер. То есть синтаксис в теории может переварить любой, нужно его только научить этому.
    Что например с точкой? Точка - большое благо и большая беда фасма, как быть с директивами '.section', '.end', '.long' и прочими? Гражданин Гриштар предлагает обрабатывать каждую строку макросом '?':
    Код (ASM):
    1. macro ? ln
    2.     match =. a,ln
    3.         match =long? c,a
    4.             long c
    5.         ;...
    6.         else match =section? c,a
    7.         else match =end? c,a
    8.         else
    9.             ln
    10.         end match
    11.     else match a =: =. b,ln
    12.         a: b
    13.     else match =and? =. =b? a,ln
    14.         and_b a
    15.     ;...
    16.     else match =!,ln
    17.     else
    18.         ln
    19.     end match
    20. end macro
    Он же поможет игнорировать комментарии, обзначенные '!' (тому кто это придумал надо памятник поставить. на могиле) В этот же макрос пойдут все инструкции, содержащие точку (чтобы использовать всю мощь нового модификатора '?' и AND.B and.b одинаково хорошо работали).
    Если ассемблер на big-endian проц, то не надо свопать байты на сдвигах, это сильно замедлит обработку. Теперь для этого есть кое-что получше:
    Код (ASM):
    1. macro rsh.long a&
    2.     iterate b,a
    3.         dd b bswap 4
    4.     end iterate
    5. end macro
    Как видно из примеров, фигурные и квадратные скобки со стенами из бекслешей больше не используются, match'и else'ятся (никаких больше '=0,done'/'done equ 1'), нету больше 'common'/'reverse' - их заменил более гибкий 'iterate'. Кстати об iterate:
    Код (ASM):
    1. macro anymacro args&
    2.     iterate i,args
    3.         indx % + 1
    4.         if %=%%-1
    5.             break
    6.         end if
    7.     end iterate
    8. end macro
    с 'indx' и 'break' стало куда интересней.
    Операнды содержат запятые? Фигня:
    Код (ASM):
    1. macro rsh.operands names,args&
    2.     local a,b,c,d,displacement,register
    3.     a equ
    4.     c equ names
    5.     iterate e,args
    6.         rmatch =@( f,e
    7.             a equ e
    8.         else rmatch =@@( f,e
    9.             a equ e
    10.         else
    11.             match a,a
    12.                 b equ a e
    13.             else
    14.                 b equ e
    15.             end match
    16.             a equ
    17.             match b,b
    18.                 match f:t,c
    19.                     c equ t
    20.                     d equ f
    21.                 else
    22.                     match c,c
    23.                         d equ c
    24.                     end match
    25.                 end match
    26.                 match d,d
    27.                     display `d,' ',`b,13,10
    28.                     ;src 0xFF
    29.                     ;dst @(R0 GBR)
    30.                 end match
    31.             end match
    32.         end rmatch
    33.     end iterate
    34. end macro
    35. macro xor_b args&
    36.     local src,dst
    37.     rsh.operands src:dst,args
    38. end macro
    39. xor_b 0xFF,@(R0,GBR)
    Все поет и пляшет и с запятыми.
    'postpone' - обрабатывается после ассемблирования, позволяет избежать одних ошибок, чтобы выводить другие :mda::
    Код (ASM):
    1. postpone
    2.     local o2
    3.     o2 equ 13,10,'displacement mod 4 must be 0',13,10
    4.     if (src.disp and 11b) <> 0
    5.         err o2
    6.     end if
    7. end postpone
    Одинарную кавычку к сожалению ни 'match', ни 'rmatch' (есть и такой) корректно не обрабатывает. Можно конечно заморочиться:
    Код (ASM):
    1. macro anymacro args&
    2.     local a,v
    3.     virtual
    4.         db `args,0,0,0,0
    5.         load a dword from $$
    6.     end virtual
    7.     if (a and 0xFFFF)=0x2768 | (a and 0xFFFF)=0x2748
    8.         virtual
    9.             db `args
    10.             v = 0
    11.             repeat $ - $$ - 2
    12.                 load a byte from $$ + 1 + %
    13.                 if a>('0'-1) & a<('9'+1)
    14.                     v = (v shl 4) or (a - '0')
    15.                 else if a>('A'-1) & a<('F'+1)
    16.                     v = (v shl 4) or (a - 'A' + 10)
    17.                 else if a>('a'-1) & a<('f'+1)
    18.                     v = (v shl 4) or (a - 'a' + 10)
    19.                 end if
    20.             end repeat
    21.             ;
    22.         end virtual
    23.     else
    24.         ;
    25.     end if
    26. end macro
    Но овчина выделки не стоит. Слишком несерьезно. Так что с конструкциями типа "#h'FFFFFFFF" можно пока распрощаться. По крайней мере до тех пор, пока match не начнет их нормально обрабатывать, либо пока не появится директива 'fix', способная "#h'" махнуть на "0x". Да, 'fix' больше нету.
    Честно говоря не знаю что и подумать но вот уж это-то точно не ожидал снова увидеть:
    Код (ASM):
    1. a equ b
    2. match a,a
    3.     display `a,13,10
    4. end match
    Без этого match'а по-прежнему получается болт на 32. И не только после присвоений, если переменная содержит точку 'src.type', та же петрушка. Но это всегда была такая особенность у фасма, не зная ее далеко не уедешь.
    Появились также звезды '*' и восклицания '!' (macro wtf?!) и несколько других новых директив, которые мне не особенно нужны были. Загляните в мануал, там интересно.
    И еще один "лайфхачик". Поскольку получившийся ассемблер не нейтив, а переваривать ему иногда придется миллионы строк, неплохо бы подумать об оптимизации. Верней думать о ней полезно всегда, но я хочу предложить неожиданный фокус. У фасма 1 два процессора команд: первичный (обрабатывает директивы 'match', 'equ', 'macro', 'struc' - тупенький, обрабатывает сравнения и присвоения строк) и вторичный ('if', 'while', 'rept', и т.д. вся арифметика и логика макроязыка на нем). Первый жрет гораздо меньше памяти и работает куда быстрей второго (для фасм 1 инфа 146%), я думаю и в фасме г ситуация должна быть схожей (match'и все так же не мешаются с if'ами, работают вообще не обращая на них внимание). Есть например формат инструкции:
    Код (Text):
    1. ;ADDV Rm, Rn ;0011nnnnmmmm1111
    Номера регистров всегда кодируются как младший или старший нибл (4 бита) байта, что соответствует правому и левому символу в 16-ричном представлении байта. Что если при разборе аргументов номера регистров задавать через equ не 0..15, а 0..f? А при ассемблировании делать:
    Код (ASM):
    1. macro addv? args&
    2.     local src,dst
    3.     rsh.operands src:dst,args
    4.     match =reg =reg m n,src.type dst.type src.reg dst.reg
    5.         db 3#n#h,0#m#fh
    6.     else
    7.         err 13,10,'syntax: ',13,10,'addv Rm,Rn',13,10
    8.     end match
    9. end macro
    Получается, что инструкции, не содержащие численных констант/смещений можно кодировать одним только первичным обработчиком. А остальным форматам инструкций без обработки полей регистров тоже станет попроще. Интелу с его 3-битными полями могли бы прекрасно зайти битовые конструкции типа '11#001#010#b', правда у Томаша в х86 ассемблере такого не наблюдаю, он там на if'ах всё заколхозил. Но художнику виднее :grin:
    На "ворошиловском мегабайте" (101071 строка кода на 943465 строк вообще) за счет апчхи-мизации разница составила примерно 4 секунды, что наверное было бы здорово, если бы это было не 77 и 73 секунды соответственно. Если первая строчка содержит ошибку, то он все равно примерно столько же будет тупить, потом ошибку отдаст. Как-то медленно запрягает наверное. На файлах поменьше скорость вполне приличная.
    Вобщем инструмент достойный, эмоции вызывает в основном положительные. Если Томаш завезет базовый комплект макросов, то точно фасм 1 отправится в музей.
     
  2. НетРегистрации

    НетРегистрации Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    72
    Так на чем писать-то свой asm - на fasm или fasm_g?
    Чуть-чуть попробовал на обоих.
    Скорости их примерно равны.
    В fasm_g не нашел listing утилит,
    неудобно с P-аддическими его отр. числами, то ли это ошибки явные, то ли мое непонимание, или возможны разные принципы их использования.
     
  3. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    18 ноября 2018 определенно надо было на фасм 1 писать. На данный момент по-прежнему нету базового набора макросов типа 'proc', 'import', 'export' и прочего, хотя вроде бы это все было обещано. Я пока фасм г рассматриваю как неплохой движок для изготовления чего-нибудь кастомного, на какой-нибудь отличной от х86 архитектуре или вообще не для исполняемых файлов. Для написания серьезных программ по-моему его пока слишком оптимистично использовать, пусть технически это уже возможно.
     
  4. НетРегистрации

    НетРегистрации Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    72
    Код (ASM):
    1. ; fasmG.izxz          ;  Hex out
    2. db  -1                ;  FF
    3. db  -1 SHR 1          ;  00
    4. db (-1 SHR 7)         ;  00
    5. db (-1 or  -1) SHR 1  ;  00
    6.  
    7. db (-1 or  -1)        ;  01
    8. db (-1 or   1)        ;  FF
    9. db (-1 or   2)        ;  FD
    10. db (-1 or   2) SHR 1  ;  FE
    11.  
    12. db (-1 or   3)        ;  FD
    13. db (-1 or   4)        ;  FB
    14. db (-1 or   5)        ;  FB
    15. db (-1 or   6)        ;  F9
    16.  
    17. db (-1 or 255)        ;  01
    18. db (-1 or 255) SHR 1  ;  80
    19. db (-1 or 255) SHR 2  ;  C0
    20. db (-1 or 255) SHR 7  ;  FE
    21.  
    22. db (-1 and -1)        ;  FF
    23. db (-1 and  1)        ;  FF
    24. db (-1 and  2)        ;  00
    25. db (-1 and  3)        ;  FF
    26.  
    27. db (-1 and  4)        ;  00
    28. db (-1 and  5)        ;  FF
    29. db (-1 and  6)        ;  00
    30. db (-1 and  7)        ;  FF
    31.  
    Мне трудновата такая математика.
    Может какую-нибудь "макроопцию" подскажешь, чтоб хоть поровнее было.
     
    Последнее редактирование: 3 сен 2020
  5. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    Фасм 1 тот же результат выдает. Типизируй число таким способом:
    Код (Text):
    1. db  (-1 and 0xFFFFFFFF) SHR 1          ;  FF
    Надеюсь идея понятна.
     
  6. НетРегистрации

    НетРегистрации Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    72
    Код (ASM):
    1.                         ; fasmw17324
    2. 00000000: FF             db   -1
    3. 00000001: 7F             db ((-1) And 255) SHR 1
    4. 00000002: 0F             db ((-1) And 255) SHR 4
    5. 00000003: 01             db ((-1) And 255) SHR 7
    6.                         ;   ^^^^^^^^^^^^^^ Я изначально пытался сделать
    7. 00000004: FF             db ( -1  And 255) SHR 1
    8. 00000005: FF             db ( -1  And 255) SHR 4
    9. 00000006: FF             db ( -1  And 255) SHR 7
    10. 00000007: FF             db (-1 and 0xFFFFFFFF) SHR 1
    11. 00000008: FF             db (-1 and 0xFFFFFFFF) SHR 4
    12. 00000009: FF             db (-1 and 0xFFFFFFFF) SHR 7
    13.                         ;
    14.                         ;db  256  ; Сообщение: не влезает
    15.                         ;db -257  ; Сообщение: не влезает
    16. 0000000A: 00             db -256  ; Нет сообщения об Ошибке
    17. 0000000B: 01             db -255  ; Нет сообщения об Ошибке
    18. 0000000C: 02             db -254  ; Нет сообщения об Ошибке
    19. 0000000D: 03             db -253  ; Нет сообщения об Ошибке
    20.                         ; И из-за такого и подобное ниже
    21. 0000000E: 90 90          Align 16
    22.                          Adr = $
    23. 00000010: 01 11 11 11    db 16 Dup (11h)
    24.           01 00 11 11  
    25.           01 FF 11 11  
    26.           11 11 11 11  
    27.                          Store Byte  -255   at Adr + 00
    28.                          Load   Tmp  Byte from Adr + 00
    29.                          Store Word   Tmp   at Adr + 04
    30.                          Store Word  -255   at Adr + 08
    31.                         ;
    32.                           Align 16
    33.                           Adr = $
    34. 00000020: FF FF FF FF     dq       -1
    35.           FF FF FF FF  
    36. 00000028: 01 00 00 00     dq       -1       ; А здесь ?
    37.           FE FF FF FF  
    38. 00000030: FF FF FF FF     dq       -1
    39.           FF FF FF FF  
    40.                          Load Tmp qword    from Adr + 00
    41.                          Tmp1 = Tmp * (-1)  ; Вообще мной неинтерпретируемый маразм.
    42.                          Store qword  Tmp1   at Adr + 08
    43.                          Tmp1 = Tmp1  SHR 63
    44.                          Store qword  Tmp1   at Adr + 12
    45.                         ;
    46.                         ; err
    47.                         ; assert 1=1
    48.                        
    49.  
     
  7. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    Я не знаю в чем твоя проблема. Если число задается в исходном тексте константой, я не задумываясь режу его маской и всё прекрасно работает. Переполнения контролирую сам, если нужно. Несколько ассемблеров на базе фасма 1 сделал и нигде не сталкивался с тем, чтоб он неверно что-то обработал.
    Код (ASM):
    1. macro itc_st32_a d,rs            {
    2.      if d eqtype 1
    3.       itc_format  0 7 0xA5, 8 11 rs,  12 15 (d shr 28), 16 21 (d and 11111b), 22 25 (d shr 10)and 1111b, 26 27 0x02, 28 31 (d shr 6)and 1111b
    4.      else
    5.       local done
    6.       done = 0
    7.       match [r1/r2+c]b,d \{
    8.            itc_format 0 7 0xA9, 8 11 rs, 12 15 r1, 16 21 (b and 0xFFFFFFFF), 22 27 0x16, 28 31 ((b and 0xFFFFFFFF) shr 6)
    9.            done = 1\}
    10.       match [r1/r2+r],d \{
    11.            itc_format 0 7 0xA9, 8 11 rs, 12 15 r1, 16 21 0, 22 27 0x06, 28 31 0
    12.            done = 1\}
    13.       match [r+]b,d \{
    14.            itc_format 0 7 0x89, 8 11 rs, 12 15 r, 16 21 (b and 0xFFFFFFFF), 22 27 0x06, 28 31 ((b and 0xFFFFFFFF) shr 6)
    15.            done = 1\}
    16.       match [+r]b,d \{
    17.            itc_format 0 7 0x89, 8 11 rs, 12 15 r, 16 21 (b and 0xFFFFFFFF), 22 27 0x16, 28 31 ((b and 0xFFFFFFFF) shr 6)
    18.            done = 1\}
    19.       match [a]b,d \{
    20.            if (done = 0&(a eq a0|a eq a1|a eq a2|a eq a3|a eq a4|a eq a5|a eq a6|a eq a7|a eq a8|a eq a9|a eq a10|a eq a11|a eq a12|a eq a13|a eq a14|a eq a15))
    21.             itc_format 0 7 0x89, 8 11 rs, 12 15 a, 16 21 (b and 0xFFFFFFFF), 22 27 0x26, 28 31 ((b and 0xFFFFFFFF) shr 6)
    22.            end if\}
    23.      end if}
     
  8. НетРегистрации

    НетРегистрации Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    72
    Код (Text):
    1.                         ; fasmw17324
    2.                         ; Даже не рассматривая создание собственных ассемблеров,
    3.                         ; как можно ему доверять в существенно более сложных
    4.                         ; случаях, когда он ошибается в простых.
    5.                        
    6.                            Virtual at 0
    7.                          ddd    db  -255
    8.                             Load Tmp Byte from ddd
    9.                            End virtual
    10.                            a = 0
    11.                            repeat  4
    12.                            a = a + Tmp
    13. 00000000: 01 00 00 00      dd a
    14. 00000004: 02 00 00 00      end repeat
    15.           03 00 00 00  
    16.           04 00 00 00  
    17.                        
    18.                            a =  -256  And 0xFFFFFFFF
    19.                            If a <> 0 ; не нулевое a в Al
    20. 00000010: B0 00            Mov Al,a  ; НетРегистрации Ошибки
    21.                            End If
    22.                        
    23.                            a = -(256) And 0xFFFFFFFF
    24.                            If a <> 0 ; не нулевое a в Al
    25. 00000012: B0 00            Mov Al,a  ; НетРегистрации Ошибки
    26.                            End If
    27.                        
    28.                            a = -(256  And 0xFFFFFFFF)
    29.                            If a <> 0 ; не нулевое a в Al
    30. 00000014: B0 00            Mov Al,a  ; НетРегистрации Ошибки
    31.                            End If
    32.                        
    33.                            a = 256
    34.                            b =   a    And 0xFFFFFFFF
    35.                            If -b <> 0 ; не нулевое -b в Al
    36. 00000016: B0 00            Mov Al,-b  ; НетРегистрации Ошибки
    37.                            End If
    38.                        
    39.                            b =   a    And 0xFFFFFFFF
    40.                            If  b <> 0 ; не нулевое -b в Al
    41. 00000018: B0 00            Mov Al,-b  ; НетРегистрации Ошибки
    42.                            End If
    43.                        
    44.                            b =  -a    And 0xFFFFFFFF
    45.                            If b <> 0 ; не нулевое b в Al
    46. 0000001A: B0 00            Mov Al,b  ; НетРегистрации Ошибки
    47.                            End If
    48.                        
    49.                            b = -( a ) And 0xFFFFFFFF
    50.                            If b <> 0 ; не нулевое a b Al
    51. 0000001C: B0 00            Mov Al,b  ; НетРегистрации Ошибки
    52.                            End If
    53.                        
    54.                            b = -( a   And 0xFFFFFFFF)
    55.                            If b <> 0 ; не нулевое a b Al
    56. 0000001E: B0 00            Mov Al,b  ; НетРегистрации Ошибки
    57.                            End If
    58.                        
    59.                         ; ну и тд и тп.
    60.                        
    61.                            a = -65536
    62.                            If a <> 0 ; не нулевое a в Ax
    63. 00000020: B8 00 00         Mov Ax,a  ; НетРегистрации Ошибки
    64.                            End If
    65.                        
    66.                            a = -65536 * 65536
    67.                            If a <> 0 ; не нулевое a в eAx
    68. 00000023: 66 B8 00 00      Mov eAx,a ; НетРегистрации Ошибки
    69.           00 00        
    70.                            End If
    71.                        
    72.  
    По моему мнению использовать безошибочно 1 Load невозможно.
    Надо 2 LoadSx как MovSx и LoadZx как MovZx, т.к. его бесконечные 2-аддические числа всегда длиннее.
    С db,dw.dd и тп вообще засада - сам программист должен контролировать переменные в них записываемые, например, резать маской по твоему совету.
    --- Сообщение объединено, 3 сен 2020 ---
    Код (Text):
    1.                            a = 0
    2.                        
    3.                            Virtual at 0
    4.                          eee    db  (-255 And 0xFFFFFFFF)
    5.                             Load Tmp Byte from eee
    6.                            End virtual
    7.                            repeat  4
    8.                            a = a + (Tmp And 0xFFFFFFFF)
    9. 00000000: 01 00 00 00      dd (a And 0xFFFFFFFF)
    10. 00000004: 02 00 00 00      end repeat
    11.           03 00 00 00  
    12.           04 00 00 00  
    13.                        
    14.                            Virtual at 0
    15.                          fff    db  -(255 And 0xFFFFFFFF)
    16.                             Load Tmp Byte from fff
    17.                            End virtual
    18.                            repeat  4
    19.                            a = a + (Tmp And 0xFFFFFFFF)
    20. 00000010: 05 00 00 00      dd (a And 0xFFFFFFFF)
    21. 00000014: 06 00 00 00      end repeat
    22.           07 00 00 00  
    23.           08 00 00 00  
    24.                        
    25.                            Virtual at 0
    26.                          ggg    db  -(255 And 0xFFFFFFFF)
    27.                             Load Tmp Byte from ggg
    28.                            End virtual
    29.                            repeat  4
    30.                            a = (a + Tmp) And 0xFFFFFFFF
    31. 00000020: 09 00 00 00      dd (a And 0xFFFFFFFF)
    32. 00000024: 0A 00 00 00      end repeat
    33.           0B 00 00 00  
    34.           0C 00 00 00  
    35.  
    А в этом фрагменте и резание перестало помогать))).
     
  9. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    НетРегистрации, 0-255=FFFFFFFFFFFFFF01. Угадай сколько будет при выборке младшего байта этого числа. И можно ли кое-кому доверять существенно более сложные случаи :acute:
     
    Последнее редактирование: 4 сен 2020
  10. НетРегистрации

    НетРегистрации Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    72
    А почему при db -257 он угадывать не хочет? Взял бы да угадал младший байт. Ну если там вообше знак потерял, а здесь -1 того же знака хоть.
    FasmG
    Adr = $
    db 16 Dup (11h)
    db -255
    db -256
    Store Byte -1 at Adr + 02
    ;Store Byte -2 at Adr + 03 ; Так нельзя, а почему у Fasm можно?
    Tmp = -2 ;;
    Store Byte Tmp at Adr + 03 ; А так можно, а было нельзя
    Tmp = -255
    Store Byte Tmp at Adr + 03 ; Те же яйца что и у db -255
    Tmp = -256 ;;
    Store Byte Tmp at Adr + 03 ; Те же яйца что и у db -256
    --- Сообщение объединено, 4 сен 2020 ---
    Выше fasmg izxz еще проверил на последнем j1br так они оба - незнаю что они куда пишут но после Store Byte -1 at Adr + 02 остается 11h другие Store нормально хоть так, хоть по разным адресам.
    --- Сообщение объединено, 4 сен 2020 ---
    А в MASM косяк следующий
    00000519 7F db -129
    0000051A 06 db -250
    0000051B 01 db -255
    db -256
    A.AS(1497) : error A2071: initializer magnitude too large for specified size
    И он ноль в байте при -256 угадать не хочет.
    Знаковые числа не надо угадывать -129< знаковый байт<128, беззнаковый другое дело, но уж если минус присутствует перед числом ,то то оно знаковое и отрицательное.
     
    Последнее редактирование: 4 сен 2020
  11. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.954
    Фасм таки может переполнения контролировать, если речь про ехать, а не про шашечки:
    Код (ASM):
    1. @@:
    2. rept 256 {
    3.     db 0
    4. }
    5. db $-@B
    Код (Text):
    1. flat assembler  version 1.71.39  (1048576 kilobytes memory)
    2.  
    3. E:\share\~~помойка\2020.09.01\Новая папка (15)\test.asm [5]:
    4. db $-@B
    5. error: value out of range.
    Ну вобщем ладно. Если понадобится совет на чем писать, а не опыты ставить, он есть выше.
     
    НетРегистрации нравится это.