flat assembler
Message board for the users of flat assembler.
Index
> Compiler Internals > [solved] Addition bug in fasm 1.73.31 |
Author |
|
pfranz 18 Oct 2023, 19:05
I am trying to report a bug but when I upload the sources I get " Tried to upload empty file"
|
|||
18 Oct 2023, 19:05 |
|
revolution 18 Oct 2023, 19:08
Describe your bug here, in text. You can use [code] and [/code] tags also.
|
|||
18 Oct 2023, 19:08 |
|
pfranz 18 Oct 2023, 20:40
Assembler snippet:
Code: align 4 RunningSum = 0 NumRep=212 REPEAT NumRep;$% / 4 LOAD Temp32bit DWord FROM $$ + (% - 1) * 4 RunningSum = (RunningSum - Temp32bit) And 0xFFFFFFFF END REPEAT dd RunningSum ;Checksum ProgSize = $% Assembly snippet: Code: xor eax, eax mov fs, ax ;fs and gs are not used mov gs, ax ;Initialize memory with 0s where needed mov ecx, BSS0size mov edi, BSS0start rep stosb ;Compute checksum right at the start, to allow subsequent modifications in ;the data loaded from disk which would cause the check to fail mov ecx, NumRep;ProgSize / 4 @@: add eax, [$$ + (ecx - 1) * 4] loop @b add eax, [$$ + ProgSize - 4] mov [ComputedSum], eax Both snippets are modified with NumRep for testing purposes. |
|||
18 Oct 2023, 20:40 |
|
revolution 18 Oct 2023, 21:32
The value of org will affect the address of [$$ + ProgSize - 4]. perhaps you meant this
Code: ProgSize = $ - $$ |
|||
18 Oct 2023, 21:32 |
|
pfranz 18 Oct 2023, 21:47
Yes, org affects that expression and does it right, because the code is executed at the right place, starting at 0x100200.
$-$$ in my case is the same as $% You can modify these expressions as you wish: the first must point to the last dword of the image, the second must hold the number of bytes (multiple of 4). This is why I was trying to post the full source, so that these expressions would certainly be correct. |
|||
18 Oct 2023, 21:47 |
|
revolution 18 Oct 2023, 21:52
If $$ == 0x100200
then ProgSize == 0x100200 + 212*4 == 0x1002D4 then [$$ + ProgSize - 4] == [0x100200 + 0x100200 + 212 * 4 - 4] == [0x2004D0] |
|||
18 Oct 2023, 21:52 |
|
pfranz 19 Oct 2023, 00:00
No. NumRep has nothing to do with ProgSize. It just for testing: the running sum only takes into account the first NumRep dwords of the image, to see when and how the error comes in. You play with NumRep in order to understand the bug.
That is why I added "add eax, [$$+ProgSize-4]": it picks the last dword (the checksum), what is normally not needed when the sum runs over the entire image. Also, note that ProgSize has nothing to do with the org at 100200,, as it is just the number of bytes of the image. $% gives an offset in the data, not an address. |
|||
19 Oct 2023, 00:00 |
|
pfranz 19 Oct 2023, 00:18
Anyway, if I can't post the full source, it doesn't make sense to reason on the assembler address symbols.
Just do a 32bit checksum of an image in the same way I did, and see the problem by changing the span of the sum: you don't need to copy the exact details of my code. |
|||
19 Oct 2023, 00:18 |
|
revolution 19 Oct 2023, 00:32
We don't know what you have done. Please post a minimal working example showing the problem. There is no need to post full source, just a handful of lines.
|
|||
19 Oct 2023, 00:32 |
|
pfranz 19 Oct 2023, 02:26
Here are 3 tests.
In each there is the image main1.bin (which differs in every test), and a test program that calculates the checksum. In the comment there are the values calculated (that you can see looking at the last dword of the output) which are wrong in the first two tests by 0x01000000.
|
|||||||||||
19 Oct 2023, 02:26 |
|
revolution 19 Oct 2023, 03:12
I agree with the fasm computation.
t.asm Code: ; cat test1/test.asm ; echo ; fasm -d DWORDS=213 -d NAME="'test1/main1.bin'" t.asm && ./t ; cat test2/test.asm ; echo ; fasm -d DWORDS=212 -d NAME="'test2/main1.bin'" t.asm && ./t ; cat test3/test.asm ; echo ; fasm -d DWORDS=200 -d NAME="'test3/main1.bin'" t.asm && ./t format elf executable SYS32_read = 3 SYS32_write = 4 SYS32_open = 5 SYS32_exit_group = 252 STDOUT_FILENO = 1 O_RDONLY = 00o MIN_ERROR = -4095 hex_table: db '0123456789abcdef' file_name db NAME,0 length = DWORDS * 4 buffer rb length entry $ mov eax,SYS32_open mov ebx,file_name mov ecx,O_RDONLY xor edx,edx ; mode int 0x80 mov bl,2 cmp eax,MIN_ERROR jae quit ; mov ebx,eax mov eax,SYS32_read mov ecx,buffer mov edx,length int 0x80 mov bl,3 cmp eax,MIN_ERROR jae quit mov esi,eax ; xor eax,eax mov ecx,length shr 2 .loop: add eax,dword[buffer + (ecx - 1) * 4] loop .loop neg eax call print_hex8 mov dl,10 call print_char mov bl,0 quit: mov eax,SYS32_exit_group movzx ebx,bl int 0x80 print_hex8: ;rax = value push ebx eax ecx edx mov ecx,8 lea ebx,[hex_table] .next_nibble: rol eax,4 mov edx,eax and edx,0xf mov dl,[ebx + edx] call print_char dec ecx jnz .next_nibble pop edx ecx eax ebx ret print_char: ;dl = character push eax ecx ebx edx mov eax,SYS32_write mov ebx,STDOUT_FILENO mov ecx,esp mov edx,1 int 0x80 pop edx ebx ecx eax ret Code: ~ cat test1/test.asm ; echo ; fasm -d DWORDS=213 -d NAME="'test1/main1.bin'" t.asm && ./t file 'main1.bin':0,213*4 RunningSum = 0 REPEAT $% / 4 LOAD Temp32bit DWord FROM $$ + (% - 1) * 4 RunningSum = (RunningSum - Temp32bit) And 0xFFFFFFFF END REPEAT dd RunningSum ;Computes and stores 0x2249DB9C instead of 0x2149DB9C flat assembler version 1.73.31 (16384 kilobytes memory) 2 passes, 1135 bytes. 2249db9c ~ cat test2/test.asm ; echo ; fasm -d DWORDS=212 -d NAME="'test2/main1.bin'" t.asm && ./t file 'main1.bin':0,212*4 RunningSum = 0 REPEAT $% / 4 LOAD Temp32bit DWord FROM $$ + (% - 1) * 4 RunningSum = (RunningSum - Temp32bit) And 0xFFFFFFFF END REPEAT dd RunningSum ;Computes and stores 0xBC4ADB9C instead of 0xBB4ADB9C flat assembler version 1.73.31 (16384 kilobytes memory) 2 passes, 1131 bytes. bc4adb9c ~ cat test3/test.asm ; echo ; fasm -d DWORDS=200 -d NAME="'test3/main1.bin'" t.asm && ./t file 'main1.bin':0,200*4 RunningSum = 0 REPEAT $% / 4 LOAD Temp32bit DWord FROM $$ + (% - 1) * 4 RunningSum = (RunningSum - Temp32bit) And 0xFFFFFFFF END REPEAT dd RunningSum ;Computes and stores 0x7A52DE09 correctly flat assembler version 1.73.31 (16384 kilobytes memory) 2 passes, 1083 bytes. 7a52de09 ~ |
|||
19 Oct 2023, 03:12 |
|
pfranz 19 Oct 2023, 05:39
It was my fault, sorry.
The snippet I use to compute the sum runs after loading DS/ES with a descriptor having the access bit reset. This descriptor is obviously part of the checksummed data. As soon as the memory is accessed, the CPU turns that bit on, thus changing the data over which the sum runs, by just one bit. Then the sum differs by 1 bit, compared to the original one. Setting the access bit in the data descriptor solves the problem. |
|||
19 Oct 2023, 05:39 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.