flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
bitRAKE 06 Jul 2022, 15:31
Art is very subjective, but I find size coding to require thinking about the instruction set differently than optimization (speed) coding. And in that regard I recently stubbled across Oscar Toledo's work. Reading the source code, I noticed he has a couple books on boot sector games programming. This might not be what you are looking for?
I've owned a number of assembly books: Mastering Turbo Assembler by Tom Swan (good copies are very expensive) All Michael Abrash's Graphics Programming books Black Book is on github Of course, the Intel Manuals can be purchased in print form. I've not bought anything recent though. Are you interested in modern coding, like 64-bit stuff, optimization, etc. Do you have an OS preference? At the other end of the spectrum I would recommend art such as http://0x80.pl/articles/ |
|||
![]() |
|
FlierMate1 07 Jul 2022, 10:55
Hotwire wrote:
bitRAKE wrote: size coding I share an "Intro to Assembly Optimization" by a security researcher (malware analyst). It has few different source files on his GitHub: https://github.com/netspooky/i2ao/tree/master/src hello.c --> bigsmile.asm --> smile.asm --> tiny.asm / smol.asm From C to Assembly. The deoptimized Assembly uses "mov rdi,0" and optimized Assembly uses "xor rdi,rdi" and several other tricks. It makes the final executable file smaller and smaller. |
|||
![]() |
|
Hotwire 08 Jul 2022, 11:07
bitRAKE, FlierMate1
Many thanks Working on a new problem I've recently realized that my assembly code is a simple translation from High Level Language to assembly (pretty much straightforward). I know several tricks but amount of these tricks is poor. |
|||
![]() |
|
bitRAKE 09 Jul 2022, 00:13
Challenge yourself by making your translation fewer lines of code than the HLL code.
For example, this Pascal code: Code: function IsVictory(Field: Field): Boolean; var Row, Col: Integer; begin with Field do for Row := 0 to Rows-1 do for Col := 0 to Cols-1 do case States[Row][Col] of Open: if Cells[Row][Col] <> Empty then Exit(False); Closed: Exit(False); Flagged: if Cells[Row][Col] <> Bomb then Exit(False); end; IsVictory := True; end; (Hint: all data elements are byte size.) Code: IsVictory: movzx eax,[rsi+FIELD.cols] ; to clear high word mul [rsi+FIELD.rows] push rsi xchg ecx,eax .keep_scanning: lodsb test al,1000_0001b ; clears carry flag jpe .false loop .keep_scanning stc .false: pop rsi retn Edit: link to larger work, to provide greater context. Last edited by bitRAKE on 09 Jul 2022, 15:05; edited 1 time in total |
|||
![]() |
|
DimonSoft 09 Jul 2022, 09:15
bitRAKE wrote:
Wow, finally a good example of PF usage. Thanks for sharing. |
|||
![]() |
|
Roman 09 Jul 2022, 12:13
Quote:
what is PF ? |
|||
![]() |
|
macomics 09 Jul 2022, 13:28
efl.pf = 4 (parity flag, bit 2)
|
|||
![]() |
|
bitRAKE 09 Jul 2022, 14:56
DimonSoft wrote: Wow, finally a good example of PF usage. Thanks for sharing. For the three bit case we have: 000, 011, 101, 110 ...even parity. Any time we can map our data model to one of these groups (or the negation), work can be eliminated. I've also seen it used to swap bits: Code: test al,0100_0010b jpe @F xor al,0100_0010b @@: [Because the flag is restricted to the low byte result.] Parity of larger sized values is bit zero of the population count. If we are doing the population count, maybe the quadrity is useful - the least two bits of count. etc. (Still, I think about it in terms of partitioning the solution space.) Code: 00000 ; quadrity= 0 01111 10111 11011 11101 11110 00001 ; quadrity= 1 00010 00100 01000 10000 11111 00011 ; quadrity= 2 00101 00110 01001 01010 01100 10001 10010 10100 11000 00111 ; quadrity= 3 01011 01101 01110 10011 10101 10110 11001 11010 11100 |
|||
![]() |
|
bitRAKE 10 Jul 2022, 01:58
Let us look at another thing - completely different and also the same: Examing the Pascal, we see a number of functions acting on the neighborhood of a cell. Each of these functions rely on a bounds checking function.
We can consolidate all these into a single general neighbor count function, but first we should resolve all these loops into a single loop. This is a verbose, data-centric view of the problem: Code: iterate <_dx,_dy>, \ -1,1, 0,1, 1,1, \ -1,0, 1,0, \ -1,-1, 0,-1, 1,-1 ; do something end iterate Code: mov ax,bx rol bx,2 sar al,6 sar ah,6 ![]() Edit: Just simple change solved the problem: Code: mov ax,bx rol bx,2 ; left or right shifts, 2 mod 4 should work: ror bx,6 perhaps sar ax,6 sar al,6 So, it might take on other uses. |
|||
![]() |
|
bitRAKE 10 Jul 2022, 15:25
Compilers often get confused by signed/unsigned numbers and the conversion between them. (Or rather, the syntactic sugar required to make them do what you want is enough to rot your teeth out!) If we stay with signed numbers the bounds checking needs both min and max test for each parameter. But we know more than the compiler and can use unsigned numbers for the bounds check - only a single check/branch for each parameter.
This is possible because the change in value is only ever +/-1; meaning 0xFF is the only underflow possible which is also the maximum unsigned value (i.e. same as an overflow). This limits our range to 0xFF (i.e. [0,0xFE]) which is not a problem in most cases. Code: macro bound_parameter parm*,delta*,range*,under_over_flow* add parm,delta ; signed cmp parm,range ; unsigned jnc under_over_flow ; unsigned end macro More generally, we can say: if the underflow does not land within the range, then a single unsigned check is possible. |
|||
![]() |
|
sleepsleep 10 Jul 2022, 16:44
Hotwire wrote: Hello there the best vault on earth https://www.pdfdrive.com/assembly-language-books.html |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.