Решил тут на днях поплотней взяться за новый фасм и определиться 'г' - 'гармония' или нечто иное? Соорудил ассемблер для Renesas SH-2A под новый фасм. Все получилось и даже работает. Фасм теперь позиционируется как 'assembler engine' - движок, а не ассемблер. То есть синтаксис в теории может переварить любой, нужно его только научить этому. Что например с точкой? Точка - большое благо и большая беда фасма, как быть с директивами '.section', '.end', '.long' и прочими? Гражданин Гриштар предлагает обрабатывать каждую строку макросом '?': Code (ASM): macro ? ln match =. a,ln match =long? c,a long c ;... else match =section? c,a else match =end? c,a else ln end match else match a =: =. b,ln a: b else match =and? =. =b? a,ln and_b a ;... else match =!,ln else ln end match end macro Он же поможет игнорировать комментарии, обзначенные '!' (тому кто это придумал надо памятник поставить. на могиле) В этот же макрос пойдут все инструкции, содержащие точку (чтобы использовать всю мощь нового модификатора '?' и AND.B and.b одинаково хорошо работали). Если ассемблер на big-endian проц, то не надо свопать байты на сдвигах, это сильно замедлит обработку. Теперь для этого есть кое-что получше: Code (ASM): macro rsh.long a& iterate b,a dd b bswap 4 end iterate end macro Как видно из примеров, фигурные и квадратные скобки со стенами из бекслешей больше не используются, match'и else'ятся (никаких больше '=0,done'/'done equ 1'), нету больше 'common'/'reverse' - их заменил более гибкий 'iterate'. Кстати об iterate: Code (ASM): macro anymacro args& iterate i,args indx % + 1 if %=%%-1 break end if end iterate end macro с 'indx' и 'break' стало куда интересней. Операнды содержат запятые? Фигня: Code (ASM): macro rsh.operands names,args& local a,b,c,d,displacement,register a equ c equ names iterate e,args rmatch =@( f,e a equ e else rmatch =@@( f,e a equ e else match a,a b equ a e else b equ e end match a equ match b,b match f:t,c c equ t d equ f else match c,c d equ c end match end match match d,d display `d,' ',`b,13,10 ;src 0xFF ;dst @(R0 GBR) end match end match end rmatch end iterate end macro macro xor_b args& local src,dst rsh.operands src:dst,args end macro xor_b 0xFF,@(R0,GBR) Все поет и пляшет и с запятыми. 'postpone' - обрабатывается после ассемблирования, позволяет избежать одних ошибок, чтобы выводить другие : Code (ASM): postpone local o2 o2 equ 13,10,'displacement mod 4 must be 0',13,10 if (src.disp and 11b) <> 0 err o2 end if end postpone Одинарную кавычку к сожалению ни 'match', ни 'rmatch' (есть и такой) корректно не обрабатывает. Можно конечно заморочиться: Code (ASM): macro anymacro args& local a,v virtual db `args,0,0,0,0 load a dword from $$ end virtual if (a and 0xFFFF)=0x2768 | (a and 0xFFFF)=0x2748 virtual db `args v = 0 repeat $ - $$ - 2 load a byte from $$ + 1 + % if a>('0'-1) & a<('9'+1) v = (v shl 4) or (a - '0') else if a>('A'-1) & a<('F'+1) v = (v shl 4) or (a - 'A' + 10) else if a>('a'-1) & a<('f'+1) v = (v shl 4) or (a - 'a' + 10) end if end repeat ; end virtual else ; end if end macro Но овчина выделки не стоит. Слишком несерьезно. Так что с конструкциями типа "#h'FFFFFFFF" можно пока распрощаться. По крайней мере до тех пор, пока match не начнет их нормально обрабатывать, либо пока не появится директива 'fix', способная "#h'" махнуть на "0x". Да, 'fix' больше нету. Честно говоря не знаю что и подумать но вот уж это-то точно не ожидал снова увидеть: Code (ASM): a equ b match a,a display `a,13,10 end match Без этого match'а по-прежнему получается болт на 32. И не только после присвоений, если переменная содержит точку 'src.type', та же петрушка. Но это всегда была такая особенность у фасма, не зная ее далеко не уедешь. Появились также звезды '*' и восклицания '!' (macro wtf?!) и несколько других новых директив, которые мне не особенно нужны были. Загляните в мануал, там интересно. И еще один "лайфхачик". Поскольку получившийся ассемблер не нейтив, а переваривать ему иногда придется миллионы строк, неплохо бы подумать об оптимизации. Верней думать о ней полезно всегда, но я хочу предложить неожиданный фокус. У фасма 1 два процессора команд: первичный (обрабатывает директивы 'match', 'equ', 'macro', 'struc' - тупенький, обрабатывает сравнения и присвоения строк) и вторичный ('if', 'while', 'rept', и т.д. вся арифметика и логика макроязыка на нем). Первый жрет гораздо меньше памяти и работает куда быстрей второго (для фасм 1 инфа 146%), я думаю и в фасме г ситуация должна быть схожей (match'и все так же не мешаются с if'ами, работают вообще не обращая на них внимание). Есть например формат инструкции: Code (Text): ;ADDV Rm, Rn ;0011nnnnmmmm1111 Номера регистров всегда кодируются как младший или старший нибл (4 бита) байта, что соответствует правому и левому символу в 16-ричном представлении байта. Что если при разборе аргументов номера регистров задавать через equ не 0..15, а 0..f? А при ассемблировании делать: Code (ASM): macro addv? args& local src,dst rsh.operands src:dst,args match =reg =reg m n,src.type dst.type src.reg dst.reg db 3#n#h,0#m#fh else err 13,10,'syntax: ',13,10,'addv Rm,Rn',13,10 end match end macro Получается, что инструкции, не содержащие численных констант/смещений можно кодировать одним только первичным обработчиком. А остальным форматам инструкций без обработки полей регистров тоже станет попроще. Интелу с его 3-битными полями могли бы прекрасно зайти битовые конструкции типа '11#001#010#b', правда у Томаша в х86 ассемблере такого не наблюдаю, он там на if'ах всё заколхозил. Но художнику виднее На "ворошиловском мегабайте" (101071 строка кода на 943465 строк вообще) за счет апчхи-мизации разница составила примерно 4 секунды, что наверное было бы здорово, если бы это было не 77 и 73 секунды соответственно. Если первая строчка содержит ошибку, то он все равно примерно столько же будет тупить, потом ошибку отдаст. Как-то медленно запрягает наверное. На файлах поменьше скорость вполне приличная. Вобщем инструмент достойный, эмоции вызывает в основном положительные. Если Томаш завезет базовый комплект макросов, то точно фасм 1 отправится в музей.
Так на чем писать-то свой asm - на fasm или fasm_g? Чуть-чуть попробовал на обоих. Скорости их примерно равны. В fasm_g не нашел listing утилит, неудобно с P-аддическими его отр. числами, то ли это ошибки явные, то ли мое непонимание, или возможны разные принципы их использования.
18 ноября 2018 определенно надо было на фасм 1 писать. На данный момент по-прежнему нету базового набора макросов типа 'proc', 'import', 'export' и прочего, хотя вроде бы это все было обещано. Я пока фасм г рассматриваю как неплохой движок для изготовления чего-нибудь кастомного, на какой-нибудь отличной от х86 архитектуре или вообще не для исполняемых файлов. Для написания серьезных программ по-моему его пока слишком оптимистично использовать, пусть технически это уже возможно.
Code (ASM): ; fasmG.izxz ; Hex out db -1 ; FF db -1 SHR 1 ; 00 db (-1 SHR 7) ; 00 db (-1 or -1) SHR 1 ; 00 db (-1 or -1) ; 01 db (-1 or 1) ; FF db (-1 or 2) ; FD db (-1 or 2) SHR 1 ; FE db (-1 or 3) ; FD db (-1 or 4) ; FB db (-1 or 5) ; FB db (-1 or 6) ; F9 db (-1 or 255) ; 01 db (-1 or 255) SHR 1 ; 80 db (-1 or 255) SHR 2 ; C0 db (-1 or 255) SHR 7 ; FE db (-1 and -1) ; FF db (-1 and 1) ; FF db (-1 and 2) ; 00 db (-1 and 3) ; FF db (-1 and 4) ; 00 db (-1 and 5) ; FF db (-1 and 6) ; 00 db (-1 and 7) ; FF Мне трудновата такая математика. Может какую-нибудь "макроопцию" подскажешь, чтоб хоть поровнее было.
Фасм 1 тот же результат выдает. Типизируй число таким способом: Code (Text): db (-1 and 0xFFFFFFFF) SHR 1 ; FF Надеюсь идея понятна.
Code (ASM): ; fasmw17324 00000000: FF db -1 00000001: 7F db ((-1) And 255) SHR 1 00000002: 0F db ((-1) And 255) SHR 4 00000003: 01 db ((-1) And 255) SHR 7 ; ^^^^^^^^^^^^^^ Я изначально пытался сделать 00000004: FF db ( -1 And 255) SHR 1 00000005: FF db ( -1 And 255) SHR 4 00000006: FF db ( -1 And 255) SHR 7 00000007: FF db (-1 and 0xFFFFFFFF) SHR 1 00000008: FF db (-1 and 0xFFFFFFFF) SHR 4 00000009: FF db (-1 and 0xFFFFFFFF) SHR 7 ; ;db 256 ; Сообщение: не влезает ;db -257 ; Сообщение: не влезает 0000000A: 00 db -256 ; Нет сообщения об Ошибке 0000000B: 01 db -255 ; Нет сообщения об Ошибке 0000000C: 02 db -254 ; Нет сообщения об Ошибке 0000000D: 03 db -253 ; Нет сообщения об Ошибке ; И из-за такого и подобное ниже 0000000E: 90 90 Align 16 Adr = $ 00000010: 01 11 11 11 db 16 Dup (11h) 01 00 11 11 01 FF 11 11 11 11 11 11 Store Byte -255 at Adr + 00 Load Tmp Byte from Adr + 00 Store Word Tmp at Adr + 04 Store Word -255 at Adr + 08 ; Align 16 Adr = $ 00000020: FF FF FF FF dq -1 FF FF FF FF 00000028: 01 00 00 00 dq -1 ; А здесь ? FE FF FF FF 00000030: FF FF FF FF dq -1 FF FF FF FF Load Tmp qword from Adr + 00 Tmp1 = Tmp * (-1) ; Вообще мной неинтерпретируемый маразм. Store qword Tmp1 at Adr + 08 Tmp1 = Tmp1 SHR 63 Store qword Tmp1 at Adr + 12 ; ; err ; assert 1=1
Я не знаю в чем твоя проблема. Если число задается в исходном тексте константой, я не задумываясь режу его маской и всё прекрасно работает. Переполнения контролирую сам, если нужно. Несколько ассемблеров на базе фасма 1 сделал и нигде не сталкивался с тем, чтоб он неверно что-то обработал. Code (ASM): macro itc_st32_a d,rs { if d eqtype 1 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 else local done done = 0 match [r1/r2+c]b,d \{ 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) done = 1\} match [r1/r2+r],d \{ itc_format 0 7 0xA9, 8 11 rs, 12 15 r1, 16 21 0, 22 27 0x06, 28 31 0 done = 1\} match [r+]b,d \{ 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) done = 1\} match [+r]b,d \{ 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) done = 1\} match [a]b,d \{ 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)) 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) end if\} end if}
Code (Text): ; fasmw17324 ; Даже не рассматривая создание собственных ассемблеров, ; как можно ему доверять в существенно более сложных ; случаях, когда он ошибается в простых. Virtual at 0 ddd db -255 Load Tmp Byte from ddd End virtual a = 0 repeat 4 a = a + Tmp 00000000: 01 00 00 00 dd a 00000004: 02 00 00 00 end repeat 03 00 00 00 04 00 00 00 a = -256 And 0xFFFFFFFF If a <> 0 ; не нулевое a в Al 00000010: B0 00 Mov Al,a ; НетРегистрации Ошибки End If a = -(256) And 0xFFFFFFFF If a <> 0 ; не нулевое a в Al 00000012: B0 00 Mov Al,a ; НетРегистрации Ошибки End If a = -(256 And 0xFFFFFFFF) If a <> 0 ; не нулевое a в Al 00000014: B0 00 Mov Al,a ; НетРегистрации Ошибки End If a = 256 b = a And 0xFFFFFFFF If -b <> 0 ; не нулевое -b в Al 00000016: B0 00 Mov Al,-b ; НетРегистрации Ошибки End If b = a And 0xFFFFFFFF If b <> 0 ; не нулевое -b в Al 00000018: B0 00 Mov Al,-b ; НетРегистрации Ошибки End If b = -a And 0xFFFFFFFF If b <> 0 ; не нулевое b в Al 0000001A: B0 00 Mov Al,b ; НетРегистрации Ошибки End If b = -( a ) And 0xFFFFFFFF If b <> 0 ; не нулевое a b Al 0000001C: B0 00 Mov Al,b ; НетРегистрации Ошибки End If b = -( a And 0xFFFFFFFF) If b <> 0 ; не нулевое a b Al 0000001E: B0 00 Mov Al,b ; НетРегистрации Ошибки End If ; ну и тд и тп. a = -65536 If a <> 0 ; не нулевое a в Ax 00000020: B8 00 00 Mov Ax,a ; НетРегистрации Ошибки End If a = -65536 * 65536 If a <> 0 ; не нулевое a в eAx 00000023: 66 B8 00 00 Mov eAx,a ; НетРегистрации Ошибки 00 00 End If По моему мнению использовать безошибочно 1 Load невозможно. Надо 2 LoadSx как MovSx и LoadZx как MovZx, т.к. его бесконечные 2-аддические числа всегда длиннее. С db,dw.dd и тп вообще засада - сам программист должен контролировать переменные в них записываемые, например, резать маской по твоему совету. --- Сообщение объединено, Sep 3, 2020 --- Code (Text): a = 0 Virtual at 0 eee db (-255 And 0xFFFFFFFF) Load Tmp Byte from eee End virtual repeat 4 a = a + (Tmp And 0xFFFFFFFF) 00000000: 01 00 00 00 dd (a And 0xFFFFFFFF) 00000004: 02 00 00 00 end repeat 03 00 00 00 04 00 00 00 Virtual at 0 fff db -(255 And 0xFFFFFFFF) Load Tmp Byte from fff End virtual repeat 4 a = a + (Tmp And 0xFFFFFFFF) 00000010: 05 00 00 00 dd (a And 0xFFFFFFFF) 00000014: 06 00 00 00 end repeat 07 00 00 00 08 00 00 00 Virtual at 0 ggg db -(255 And 0xFFFFFFFF) Load Tmp Byte from ggg End virtual repeat 4 a = (a + Tmp) And 0xFFFFFFFF 00000020: 09 00 00 00 dd (a And 0xFFFFFFFF) 00000024: 0A 00 00 00 end repeat 0B 00 00 00 0C 00 00 00 А в этом фрагменте и резание перестало помогать))).
НетРегистрации, 0-255=FFFFFFFFFFFFFF01. Угадай сколько будет при выборке младшего байта этого числа. И можно ли кое-кому доверять существенно более сложные случаи
А почему при 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 --- Сообщение объединено, Sep 4, 2020 --- Выше fasmg izxz еще проверил на последнем j1br так они оба - незнаю что они куда пишут но после Store Byte -1 at Adr + 02 остается 11h другие Store нормально хоть так, хоть по разным адресам. --- Сообщение объединено, Sep 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, беззнаковый другое дело, но уж если минус присутствует перед числом ,то то оно знаковое и отрицательное.
Фасм таки может переполнения контролировать, если речь про ехать, а не про шашечки: Code (ASM): @@: rept 256 { db 0 } db $-@B Code (Text): flat assembler version 1.71.39 (1048576 kilobytes memory) E:\share\~~помойка\2020.09.01\Новая папка (15)\test.asm [5]: db $-@B error: value out of range. Ну вобщем ладно. Если понадобится совет на чем писать, а не опыты ставить, он есть выше.