flat assembler
Message board for the users of flat assembler.

Index > Windows > Access violation, Write Address = ffffffc

Author
Thread Post new topic Reply to topic
Sloppysecond



Joined: 01 May 2017
Posts: 8
Sloppysecond
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 number, quantity_of_digits
{
        local looping
        
        xor ecx, ecx
        xor eax, eax
        xor edx, edx
        
        or ecx, quantity_of_digits ;Command loop will use register ecx
looping : 
        mov dh, [number + eax]
        or dh, 030h
        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 GetStdHandle, STD_OUTPUT_HANDLE
        mov [handle_to_output_stream], eax 
        
        if first_number_length >= second_number_length
                mov eax, second_number_length
                mov esi, first_number_length 
        else
                mov eax, first_number_length
                mov esi, second_number_length 
        end if
        mov ecx, eax
        
        dec esi
        mov ebp, first_number_length
        mov esp, second_number_length 
        
        dec ebp
        dec esp 
        
        xor eax, eax
        xor ebx, ebx
        xor edx, edx

        
        mov al, [first_number+ ebp]
        mov ah,[first_number+ ebp - 1] 
        shl ah, 4 
        or al, ah 
        
        add al, [second_number+ esp] 
        daa 
        adc ah, 0
        
        or dl, al 
        and dl, 0Fh 
        mov [result+esi], dl 
        
        shr ax, 4 

        dec esi
        dec esp
        
        dec ebp 
        dec ebp
        
        dec ecx 
        
        xor dl, dl
        
for_looping : 
        dont_get_last_digit : 
        
        mov ah,[first_number+ebp] 
        shl ah, 4
        or al, ah 
        
        add al, [second_number+esp] 
        daa 
        adc ah, 0
        
        or dl, al 
        and dl, 0Fh 
        mov [result+esi], dl
        
        CMP esp, 0
        je break1
        
        CMP esi, 0
        je break2
        
        dec esi
        dec esp
        shr ax, 4
        xor dl, dl
        
        CMP ebp, 0
        je dont_get_last_digit
        
        dec ebp
loop for_looping

break1 : 
break2 :

        set_ascii_code result, first_number_length
        invoke WriteConsole, [handle_to_output_stream],result, first_number_length, symbols_was_written , reserved
        
        
FINISH :
    pop eax
        pop ebx 
        pop ecx
        pop esi
        pop ebp
        pop esp
        pop edx 
                
        invoke  ExitProcess, 0
        
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: 17472
Location: In your JS exploiting you and your system
revolution
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
Sloppysecond
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: 17472
Location: In your JS exploiting you and your system
revolution
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
Sloppysecond
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: 81
Location: Minsk, Belarus
VEG
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
Sloppysecond
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
Sloppysecond
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: 17472
Location: In your JS exploiting you and your system
revolution
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
Sloppysecond
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


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.