Using assembly code, some questions

General discussion on mikroPascal PRO for PIC32.
Post Reply
Author
Message
tormod
Posts: 57
Joined: 29 Nov 2004 16:31

Using assembly code, some questions

#1 Post by tormod » 30 Sep 2018 21:46

Has made the following function in MIPS assembler:

function __SkrASMFindAByte(Destination: ^byte; Len,Ctr: word; Ch: byte) : word;

// ****************************************************************************************
//
// function __SkrASMFindAByte(Destination: ^byte; Len,Ctr: word; Ch: byte) : word;
//
// This routine searches through <Destination> buffer upto and inclusive <Len> for the
// <Ch> byte. <Ctr> indicate number of <Ch> before stop. Routine returns position of the
// <Ch> between 0-0xFFFF-1. If not found routine returns 0xFFFF.
// R6: found Ch ctr, R4: load byte register, R5: loop counter
//
// ****************************************************************************************

begin
asm

add R6, R0, R0 ; set Ch ctr to zero
add R5, R0, R0 ; set loop to zero

L___SkrASMFindAByte01:

beq R5, R26, L___SkrASMFindAByte04 ; if long loop = Len then we are done
NOP
lb R4, 0(R25) ; get byte
beq R4, R28, L___SkrASMFindAByte03 ; if byte equals Ch go to count check
NOP

L___SkrASMFindAByte02:

addiu R25, R25, 1 ; next address
addiu R5, R5, 1 ; loop = loop + 1
beq R0, R0, L___SkrASMFindAByte01 ; next byte
NOP

L___SkrASMFindAByte03: ; check Ctr

addiu R6, R6, 1 ; add found Ch ctr
beq R6,R27,L___SkrASMFindAByte04 ; if no of found Ch equals Ctr then exit
NOP
beq R0,R0, L___SkrASMFindAByte02 ; not done yet
NOP

L___SkrASMFindAByte04:

bne R6,R0,L___SkrASMFindAByte05 ; if Ch ctr = 0, byte not found
NOP
ori R5,R0,65535 ; set result to 0xFFFF

L___SkrASMFindAByte05:

end;
result := R5;
end;

and it do work, but I have some interesting questions, using Rx notation on register is better than original MIPS. But it does not seems that you follow the restrictions
on use of registers as in standard MIPS, I guess that any register except R0 can be used for any purpose. R25,R26 and further is used for parameters sent to routines, which is not standard MIPS. Does max 4 parameters do apply before using the stack? R2 which contain return values from functions is also freely used. You can not set return value to R2 in a function, the compiler will issue a fault that return value is not defined, but you can set result := Rx which is decoded as a move from Rx to R2. Can not anyone write a short tutorial on this issue, because assembler runs faster than code generated by compiler and can be useful for small tidious tasks. Briefly checked the MemMove routine which moves bytes between memory locations, more than 200 bytes, my first MIPS routine do the same, but rather tries to move 4 bytes (dword) rather than bytes. This routine is 80 bytes, and will probably runs faster also - so there might be a lot to win doing it with MIPS. I also want to know about use of NOP, with basic test my move routine do work fine without any NOP on branches, while the above function must have the NOP's, otherwise registers will not be correct.

tormod
Posts: 57
Joined: 29 Nov 2004 16:31

Re: Using assembly code, some questions

#2 Post by tormod » 03 Oct 2018 11:30

The most important question is: MIPS define safe registers of which content need not to be saved before use, which of registers R1-R30 are "safe"?

User avatar
petar.suknjaja
mikroElektronika team
Posts: 683
Joined: 05 Mar 2018 09:44
Location: Belgrade

Re: Using assembly code, some questions

#3 Post by petar.suknjaja » 04 Oct 2018 16:21

Hi Tormod,
I will ask our developers about the information which of the registry banks are safe to use.
I just need one more thing, could you tell me in more details what's wrong with the registers when the NOP is not used -
what kind of problem does it make? Wrong registers, wrong values?

Kind regards,
Petar

tormod
Posts: 57
Joined: 29 Nov 2004 16:31

Re: Using assembly code, some questions

#4 Post by tormod » 04 Oct 2018 21:36

The NOP's are used because of instruction fetching of MIPS, I have not studied this in detail but in fact MIPS fetches next instruction without finishing the current instruction and of course this will come out wrongly. In your code you are consequent adding NOP to any branch, but experiments show it is not always necessary, but I have to study Mips in detail toknow, I have studied MIPS just a couple of days - if not anybody else already has done this and can enlighten us. This is purely related to MIPS, and work the same way on other processors/controllers.

An other nuisance is related to debugger, if you program a string and set the end of string as Str[N] := #0; (NUL) this will not show in the debugger watch window, so to make sure that you have placed it right you must use an other ascii character e.g. Str[N] := 'X', this should be fixed because it creates a lot of extra work. What it writes today is '' like all other empty places in the string, and it is impossible to see where the 0 goes, it does not even change color as other position in the string do(black to red).

User avatar
rajkovic
mikroElektronika team
Posts: 694
Joined: 16 Aug 2004 12:40

Re: Using assembly code, some questions

#5 Post by rajkovic » 10 Oct 2018 14:50

Does max 4 parameters do apply before using the stack?
With SSA optimization on compiler will first use regs for parameters (R25-R28) rest of params will be on the stack.
(MZ family also have dedicated register for float, double and first will use S12-S15 for passing this type of params and then use stack)
Note: disabling optimization and SSA will change behaviour of compiler.


R2 which contain return values from functions is also freely used.
Yes
You can not set return value to R2 in a function, the compiler will issue a fault that return value is not defined, but you can set result := Rx which is decoded as a move from Rx to R2.
Actually this is false alarm from compiler if you result value to R2 in asm it will be passed, but compiler does not recognise this.




Can not anyone write a short tutorial on this issue
I agree it should be done, will try to do it in near future.
I also want to know about use of NOP, with basic test my move routine do work fine without any NOP on branches, while the above function must have the NOP's, otherwise registers will not be correct.

It is called Delay Slot Instruction (MIPS specific)

On the MIPS architecture, jump and branch instructions have a "delay slot". This means that the instruction after the jump or branch instruction is executed before the jump or branch is executed.

In addition, there is a group of "branch likely" conditional branch instructions in which the instruction in the delay slot is executed only if the branch is taken.

The MIPS processors execute the jump or branch instruction and the delay slot instruction as an indivisible unit. If an exception occurs as a result of executing the delay slot instruction, the branch or jump instruction is not executed, and the exception appears to have been caused by the jump or branch instruction.

More details could be found in MIPS instruction reference manual for specific core.

Post Reply

Return to “mikroPascal PRO for PIC32 General”