Page 1 of 1

HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 10:50 am
by Jlouro
I was reading this ATA read/write sectors to read IDE through ports.

I made this assembly code:

Code: Select all

;-----------------------------------Disk Start-----------------------------------------;
global _readd
global _writed

;--------------------------------Read Disk Start---------------------------------------;

_readd:

 ;push eax
 ;push ebx
 ;push ecx
 ;push edx

 push ebp
 mov ebp, esp
 mov eax, [ebp+8] ;first parameter
 mov ecx, eax
 cmp ecx, 256
 jg short _readsector_fail
 jne short _readsector
 xor ecx, ecx

_readsector:
 mov ebx, ecx
 mov eax, [ebp+12] ;second parameter
 cmp eax, 0
 je _readsector_fail

 push eax ;sector number
 mov dx, 0x1f2
 mov al, cl
 out dx, al
 inc dx ;dx = 0x1f3
 pop eax
 out dx, al
 inc dx ;dx = 0x1f4
 shr eax, 8
 out dx, al
 inc dx ;dx = 0x1f5
 shr eax, 8
 out dx, al
 inc dx ;dx = 0x1f6
 shr eax, 8
 and al, 00001111b
 or al, 01000000b
 out dx, al
 inc dx ;dx = 0x1f7
 mov al, 0x20
 out dx, al

 mov ecx, 4
_readsector_wait:
 in al, dx
 test al, 0x80 ; BSY
 jne _readsector_retry
 
 test al, 0x08 ; DRQ
 jne _readsector_ready

_readsector_retry:
 dec ecx
 jg _readsector_wait

_readsector_nextsector:
 in al, dx
 test al, 0x80
 jne _readsector_nextsector

 test al, 0x21
 jne _readsector_fail

_readsector_ready:
 sub dx, 7 ;0x1f0
 mov ecx, 256
 rep insw
 add dx, 7
 in al, dx ;wait 400 ns
 in al, dx
 in al, dx
 in al, dx
 
 dec ebx
 jg _readsector_nextsector
 ;mov eax, edi
 ;cmp eax, 0x0ffffffff
 ;jz _readsector_fail
 mov [ebp-8], edi ;Second local variable
 leave
 ret

_readsector_fail:
 xor eax, eax
 leave
 ret


;-----------------------Read Disk End-------------------------------------;
It is always printing a comma. Is it legal to do that mov [ebp-8], edi ?

In this same file I have writedisk and I mov esi, [ebp-4] (which is the first local variable).

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:01 am
by iansjack
I find it very difficult to follow your code as there are no useful comments and no indication of what the parameters and variables represent. A couple of questions:

1. What do you mean by "printing a comma". Unless I missed something I see no calls to print routines.

2. You don't seem to ever use EDI or assign anything to it and then, out of nowhere, you assign its value to a local variable. Why? Especially as you then immediately leave the function.

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:03 am
by BASICFreak
Can you please rephrase your question?
It is always printing a comma. Is it legal to do that mov [ebp-8], edi ?
I see nowhere in that code segment that has anything to do with printing or a comma.

And yes; mov [ebp - 8], edi is fully legal.

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:05 am
by Jlouro
iansjack wrote:I find it very difficult to follow your code as there are no useful comments and no indication of what the parameters and variables represent. A couple of questions:

1. What do you mean by "printing a comma". Unless I missed something I see no calls to print routines.

2. You don't seem to ever use EDI or assign anything to it and then, out of nowhere, you assign its value to a local variable. Why? Especially as you then immediately leave the function.
I'm not used to work with EDI. I have a kernel.c with PrintString. You want me to post here my kernel.c code?

When I rep insw It should retrieve the value to edi right? My ebp-8 is a local variable in c

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:09 am
by Jlouro
BASICFreak wrote:Can you please rephrase your question?
It is always printing a comma. Is it legal to do that mov [ebp-8], edi ?
I see nowhere in that code segment that has anything to do with printing or a comma.

And yes; mov [ebp - 8], edi is fully legal.

Code: Select all

extern int _readd(int sector_count, int nmrsector);
extern int _writed(int sector_count, int nmrsector);

void kmain()
{
	int msg = 104;
	int recv;
	int sector = 1;
	int read = 1;
	int writeerror = _writed(read, sector);
	if(writeerror == 0) PrintString("Error Writing\n");
	int error = _readd(read, sector);
	if(error == 0) PrintString("ERROR");
	PrintChar((char)recv);
	PrintChar('\n');
	PrintString("READ!");
	readStr();
}
That's my kernel.c file. I'm probably printing that wrong.
ebp-8 will be recv right?

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:14 am
by BASICFreak
INSW - reads word from port DX into address ES:(E)DI

You have not set EDI, insw will not set it, only increase it by 2 for each word you read from port DX. (without setting (E)DI you can be overwriting anything)

http://x86.renejeschke.de/html/file_mod ... d_141.html
ebp-8 will be recv right?
No, if you want to pass recv - pass it as an argument do not rely on the stack to have the value - it's probably in the .BSS section.

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:24 am
by Jlouro
BASICFreak wrote:INSW - reads word from port DX into address ES:(E)DI

You have not set EDI, insw will not set it, only increase it by 2 for each word you read from port DX. (without setting (E)DI you can be overwriting anything)

http://x86.renejeschke.de/html/file_mod ... d_141.html
ebp-8 will be recv right?
No, if you want to pass recv - pass it as an argument do not rely on the stack to have the value - it's probably in the .BSS section.

so is it better to do: _readd(int, int, int) and then make mov edi, [ebp+16] ?

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:50 am
by BASICFreak
so is it better to do: _readd(int, int, int) and then make mov edi, [ebp+16] ?
The way a standard C call works, any modification to the values passed to the function will be lost. The only way to keep the value is to pass it as a pointer (int*) and modify it in memory.

Here is your call frame.

e.g.:

Code: Select all

_readd(int*, int, int)
_readd(&recv, read, sector)

mov ebx, [ebp + 12] ; I may be wrong with the 12 here
mov [ebx], edi

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 11:57 am
by iansjack
Jlouro wrote:
BASICFreak wrote: ebp-8 will be recv right?
Wrong!

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 12:00 pm
by Jlouro
BASICFreak wrote:
so is it better to do: _readd(int, int, int) and then make mov edi, [ebp+16] ?
The way a standard C call works, any modification to the values passed to the function will be lost. The only way to keep the value is to pass it as a pointer (int*) and modify it in memory.

Here is your call frame.

e.g.:

Code: Select all

_readd(int*, int, int)
_readd(&recv, read, sector)

mov ebx, [ebp + 12] ; I may be wrong with the 12 here
mov [ebx], edi
One more question:

Code: Select all

_asm_function(int a, int b, int c)

mov ebx, [ebp+12]
In that code am I moving my variable b to ebx ? I read that in C arguments are passed left-to-right and [ebp+4] is the return.
So [ebp+8] will be int a;
[ebp+12] will be int b;
[ebp+16] will be int c. Right?

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 12:08 pm
by BASICFreak
It's pushed Right to Left

So your pushes onto the stack are

push C (+20)
push B (+16)
push A (+12)
push ReturnAddress (+8)
push EBP (+4)

Re: HardDrive - PMode x86 assembly

Posted: Sat Feb 20, 2016 12:10 pm
by iansjack
You know, there is an easy way to test this sort of question. Run your code in a debugger and look at what actually happens.