flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
revolution 23 Mar 2022, 20:52
In x86 code you can't store more than 4 bytes of immediate data into memory with a single instruction.
Your constant '0123456789ABCDEF' is 16 bytes. And your storage space .itoa_idx is one byte. Something like this maybe: Code: .itoa_idx rb 16 ; reserve 16 bytes ;... mov dword[.itoa_idx + 0], '0123' mov dword[.itoa_idx + 4], '4567' mov dword[.itoa_idx + 8], '89AB' mov dword[.itoa_idx +12], 'CDEF' Code: .itoa_idx db '0123456789ABCDEF' |
|||
![]() |
|
macomics 23 Mar 2022, 21:16
newtrix wrote:
You can allocate a local variable for a function in the stack: Code: itoa: label .itoa_idx byte at rbp-16 push rbp mov rbp, rsp sub rsp, 16 mov [.itoa_idx + 0], '0';'0123456789ABCDEF' mov [.itoa_idx + 1], '1' mov [.itoa_idx + 2], '2' mov [.itoa_idx + 3], '3' mov [.itoa_idx + 4], '4' mov [.itoa_idx + 5], '5' mov [.itoa_idx + 6], '6' mov [.itoa_idx + 7], '7' mov [.itoa_idx + 8], '8' mov [.itoa_idx + 9], '9' mov [.itoa_idx + 10], 'A' mov [.itoa_idx + 11], 'B' mov [.itoa_idx + 12], 'C' mov [.itoa_idx + 13], 'D' mov [.itoa_idx + 14], 'E' mov [.itoa_idx + 15], 'F' ;OR mov dword [.itoa_idx + 0], '0123';'0123456789ABCDEF' mov dword [.itoa_idx + 4], '4567' mov dword [.itoa_idx + 8], '89AB' mov dword [.itoa_idx + 12], 'CDEF' ... ;CLEAR mov rsp, rbp pop rbp ret Or define it in the data section as global: Code: itoa: ... segment readwble writeable itoa.itoa_idx db '0123456789ABCDEF' revolution wrote:
And if you use 32-bit code, then you can do without an indexing table at all: Code: itoa:cmp al, 10 cmc adc al, '0' daa ; Invalid, in 64-bit code ... Last edited by macomics on 23 Mar 2022, 21:36; edited 2 times in total |
|||
![]() |
|
revolution 23 Mar 2022, 21:31
There is also a three instruction conversion.
Code: cmp al,10 sbb al,0x69 das |
|||
![]() |
|
macomics 23 Mar 2022, 21:40
revolution wrote: There is also a three instruction conversion. I do not know why lowercase characters may be needed instead of numbers. Only with uppercase numbers look better. |
|||
![]() |
|
revolution 23 Mar 2022, 22:05
I don't like either of them. The three or four instruction converters are terrible actually, IMO.
But they are "cool tricks", so they do have some value I guess. ![]() Way back in the good-old-days when saving a few bytes of RAM was vital, and clock counts could be computed by sight, these codes could have been life savers. Now I have GiBs of RAM and clock counts are buried sixteen dimensions deep and impossible to visualise unless you are an advanced level hyper-god. ![]() |
|||
![]() |
|
macomics 23 Mar 2022, 22:14
revolution wrote: I don't like either of them. The three or four instruction converters are terrible actually, IMO. |
|||
![]() |
|
bitRAKE 24 Mar 2022, 00:55
|
|||
![]() |
|
newtrix 24 Mar 2022, 23:08
Wow, thanks for all the replies to this. The very first solution(s) worked just fine, and I have a working itoa now. Is it appropriate for me to put it in code blocks and ask for critiques/suggestions?
EDIT: I'll look at those neat tricks you guys showed for conversion. At a glance I presume they also only work for base 10? Mine is meant to work for any base < 17. |
|||
![]() |
|
revolution 25 Mar 2022, 00:48
newtrix wrote: EDIT: I'll look at those neat tricks you guys showed for conversion. At a glance I presume they also only work for base 10? So as mentioned, not very flexible. And not universal. |
|||
![]() |
|
macomics 25 Mar 2022, 07:43
how it works
Code: cmp al, 10 ; al= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |... cmc ; al= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |... adc al, '0' ; al= '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ';' '<' '=' '>' '?' '@' 'A' ... daa ; al= '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' 'A' ... Code: cmp al, 10 ; al= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |... sbb al, 105 ; al= x96|x97|x98|x99|x9A|x9B|x9C|x9D|x9E|x9F|xA1|xA2|xA3|xA4|xA5|xA6|xA7|... das ; al= '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' 'A' ... To translate a byte consisting of 2 characters, this is even still relevant in 32-bit programs. The advantages can also include the fact that the translation of the sign is carried out in a limited space. There is no need to release an entire 32/64-bit register to access the table. To translate a 16/32/64-bit value, you should use a different algorithm. Although it is still possible to discuss about the 16-bit value, but for 32-bit and 64-bit values, you can write more efficient variants of parallel translation of all 4-bit-groups in a number. One of the options for translating the 64-bit value was given by bitRAKE. But for a 32-bit program, it is not obvious that the processor has the SSE3 extension. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.