flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Windows > Access violation, Write Address = ffffffc

Author
Thread Post new topic Reply to topic
Sloppysecond



Joined: 01 May 2017
Posts: 8
Access violation, Write Address = ffffffc
Hello there!
I'm trying to make sum with two length numbers using fasm.
But in the end of the program i catch exception which was mentioned in the title of the topic.
I wasted some hours to correct it and remade my program 3 times but every time i face this problem and only addresses of the error were changed.
Here is my code :

Code:
format  PE      Console 
entry   start                   

include 'C:\FASM\INCLUDE\win32a.inc'

macro set_ascii_code numberquantity_of_digits
{
        local looping
        
        xor ecxecx
        xor eaxeax
        xor edxedx
        
        or ecxquantity_of_digits ;Command loop will use register ecx
looping : 
        mov dh, [number + eax]
        or dh030h
        mov [number + eax], dh
        inc eax
loop looping
}


section '.data' data readable writeable
first_number db 1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 
first_number_length   =   $ - first_number 
max_length dw 0

second_number db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
second_number_length = $ - second_number  

result db 100 dup(0)

handle_to_output_stream dd 0
reserved dd 0
symbols_was_written dd 0

section '.code' code readable executable
start:
        push eax
        push ebx 
        push ecx
        push esi
        push ebp
        push esp
        push edx 
        
        invoke GetStdHandleSTD_OUTPUT_HANDLE
        mov [handle_to_output_stream], eax 
        
        if first_number_length >= second_number_length
                mov eaxsecond_number_length
                mov esifirst_number_length 
        else
                mov eaxfirst_number_length
                mov esisecond_number_length 
        end if
        mov ecxeax
        
        dec esi
        mov ebpfirst_number_length
        mov espsecond_number_length 
        
        dec ebp
        dec esp 
        
        xor eaxeax
        xor ebxebx
        xor edxedx

        
        mov al, [first_numberebp]
        mov ah,[first_numberebp - 1
        shl ah4 
        or alah 
        
        add al, [second_numberesp
        daa 
        adc ah0
        
        or dlal 
        and dl0Fh 
        mov [result+esi], dl 
        
        shr ax4 

        dec esi
        dec esp
        
        dec ebp 
        dec ebp
        
        dec ecx 
        
        xor dldl
        
for_looping : 
        dont_get_last_digit : 
        
        mov ah,[first_number+ebp
        shl ah4
        or alah 
        
        add al, [second_number+esp
        daa 
        adc ah0
        
        or dlal 
        and dl0Fh 
        mov [result+esi], dl
        
        CMP esp0
        je break1
        
        CMP esi0
        je break2
        
        dec esi
        dec esp
        shr ax4
        xor dldl
        
        CMP ebp0
        je dont_get_last_digit
        
        dec ebp
loop for_looping

break1 : 
break2 :

        set_ascii_code resultfirst_number_length
        invoke WriteConsole, [handle_to_output_stream],resultfirst_number_lengthsymbols_was_written , reserved
        
        
FINISH :
    pop eax
        pop ebx 
        pop ecx
        pop esi
        pop ebp
        pop esp
        pop edx 
                
        invoke  ExitProcess0
        
section '.idata' import readable
        library kernel'KERNEL32.DLL',\
                        ascidc,         'ascidc.dll'
import  kernel,\        
                        ExitProcess,    'ExitProcess',\
                        GetStdHandle,   'GetStdHandle',\
                        WriteConsole,   'WriteConsoleA',\
                        GetCurrentDirectory,    'GetCurrentDirectoryA',\
                        CloseHandle,    'CloseHandle',\
                        CreateFile,             'CreateFileA',\
                        ReadFile,               'ReadFile',\
                        WriteFile,              'WriteFile',\
                        GetCommandLine'GetCommandLineA',\
                        VirtualFree,    'VirtualFree',\
                        VirtualAlloc,   'VirtualAlloc',\
                        SetFilePointer'SetFilePointer',\
                        GetFileSize,    'GetFileSize',\
                        ReadConsole,    'ReadConsoleA'
                        
import  ascidc,\
                        GetSPSTR,       'GetSPSTR',\
                        ASCIINH,                'ASCIINH',\
                        NHASCII,                'NHASCII' 

Post 01 May 2017, 13:51
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15094
Location: The Unicomplex
PUSH and POP must be in reverse order from each other.

BTW: For Windows you only need to preserve EBX, EBP, ESI and EDI.
Post 01 May 2017, 14:00
View user's profile Send private message Visit poster's website Reply with quote
Sloppysecond



Joined: 01 May 2017
Posts: 8

revolution wrote:
PUSH and POP must be in reverse order from each other.

BTW: For Windows you only need to preserve EBX, EBP, ESI and EDI.


Thank you.
Now i've got such code :

Code:
push eax
        push ebx 
        push ecx
        push esi
        push ebp
        push esp
        push edx 
..................................
FINISH :
        pop edx
        pop esp
        pop ebp
        pop esi
        pop ecx
        pop ebx
        pop eax




But anyway i'have got this exception in the end of the program.
Post 01 May 2017, 14:29
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15094
Location: The Unicomplex
It probably isn't a good idea to be PUSHing or POPing ESP. Also you can't use ESP as a general purpose register like that. Remember that ESP is the stack pointer so after you change it your stack is now lost.
Post 01 May 2017, 14:42
View user's profile Send private message Visit poster's website Reply with quote
Sloppysecond



Joined: 01 May 2017
Posts: 8

revolution wrote:
It probably isn't a good idea to be PUSHing or POPing ESP. Also you can't use ESP as a general purpose register like that. Remember that ESP is the stack pointer so after you change it your stack is now lost.


Ouch i didn't think about that.
Will correct code using EDI.
Post 01 May 2017, 14:50
View user's profile Send private message Reply with quote
VEG



Joined: 06 Feb 2013
Posts: 69
Location: Minsk, Belarus
Sloppysecond, it is better to use pushad and popad in your situation. It preserves/restores all registers in one command.
Post 01 May 2017, 15:17
View user's profile Send private message Visit poster's website Reply with quote
Sloppysecond



Joined: 01 May 2017
Posts: 8

revolution wrote:
Remember that ESP is the stack pointer so after you change it your stack is now lost.


Thank you!
The problem was solved by changing using of ESP on the EDI.
I guess without you i would kill many hours to understand this.
Can you answer me on the theoretical question :
1)Why do we need to push some registers and after using pop them?
From that do we preserve them? From changing by other threads?
I have never did it before and used only ECX, EBX, EDX and EAX. But in this task more registers were needed.
Post 01 May 2017, 15:29
View user's profile Send private message Reply with quote
Sloppysecond



Joined: 01 May 2017
Posts: 8

VEG wrote:
Sloppysecond, it is better to use pushad and popad in your situation. It preserves/restores all registers in one command.


Thank you, i didn't know about this commands. Will read about them.
Post 01 May 2017, 15:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15094
Location: The Unicomplex
When you PUSH you save the value on the stack, and later you POP to recover the original value. It is part of the Windows calling standard, all functions are expected to not corrupt EBX, EBP, ESI and EDI.
Post 01 May 2017, 15:34
View user's profile Send private message Visit poster's website Reply with quote
Sloppysecond



Joined: 01 May 2017
Posts: 8

revolution wrote:
When you PUSH you save the value on the stack, and later you POP to recover the original value. It is part of the Windows calling standard, all functions are expected to not corrupt EBX, EBP, ESI and EDI.


Thank you.
Post 01 May 2017, 15:39
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.