You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
Given: n() is an array of LONG integers, with zero-based subscripts
Also Given:
PowerBASIC stores arrays in column-major order: Array(0,0) is first (lowest) in memory, then Array(1,0), then Array(2,0), and so on through all the rows of the array. After the rows are taken care of, the next column is stored
.. then I better fix my original plan, since I thought it was row-major order before I RTFM..
I suspected "learning assembly language" was probably the real goal here.
I guess I was just hoping the Real Goal (not shown) was, "I want to do something faster and think I can use the posted assembly language code to do it" and that alternate solutions would be, if not welcomed with open arms, at least accepted in good faith.
The latter is the prime driver. As Bob points out, my programming language of choice is PowerBASIC because it does >99.99% of what I want and need in a way I can understand and at a speed far in excess of anything else I've used which also is plenty fast enough >99.99% of the time.
That said, there are times where a little more speed would be handy and, again, PowerBASIC comes up trumps by allowing me to most easily incorporate assembler directly into my programs.
I am, at heart, a simple and old fashioned BASIC programmer from the days when the BASIC came with the machine. I understand the concepts of pointers (and again, PB makes these trivial to implement) and other constructs and I do like to learn new things to add tools to the toolbox as it were.
Looking at Paul and Bob's answers, it's clearer to me (so I learned something) that arrays in assembler effectively need to be treated like arrays accessed by pointers in PB. That makes sense to me and I'm happy I've learned a bit more about PB and Assembler from the question and it's prompted a bit of debate too so it's all good. I also think Michael's suggested cheat/trick could work for me. I need to play some with the code in the answers and, for me at least, that's what this is all about. It's just a hobby to me. Thanks again to everyone.
>Maybe an array element referenced by subscript is not eligible for direct use?
This usage is somewhat like an array subscript, and can be used with some other data types too.
Code:
#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
LOCAL sArr AS STRING * 32
sArr = CHR$(49 TO 80)
'think of it kinda like: DIM sArr(32) AS BYTE AT VARPTR(s)
!mov al, sArr[0] ;"1" is the chr moved to al
!mov al, sArr[1] ;"2"
!mov al, sArr[2] ;3
!mov al, sArr[3] ;4
!mov al, sArr[4] ;5
!mov al, sArr[24] ;I
!mov al, sArr[25] ;J
!mov al, sArr[31] ;P
END FUNCTION
I suspected "learning assembly language" was probably the real goal here.
I guess I was just hoping the Real Goal (not shown) was, "I want to do something faster and think I can use the posted assembly language code to do it" and that alternate solutions would be, if not welcomed with open arms, at least accepted in good faith.
Michael,
the purpose is to learn to do in assembler what is currently done in BASIC in order to become more proficient at programming in assembler.
Bypassing the tricky bits using BASIC doesn't help with that objective.
The essence of the problem is this... When you write ASM code, you must use Intel opcodes. ADD EAX, n(g,a) is not an Intel opcode. That type of operation requires the execution of numerous Intel opcodes, which vary greatly depending upon the nature of the array and the nature of the reference.
That's one of the good reasons you chose PowerBASIC. It handles all of that messy stuff automatically when you code in PowerBASIC syntax.
Help does not say if array elements may/may not be referenced directly in ASM statements:
Accessing PowerBASIC variables by name
Most variables in a PowerBASIC module are visible to Inline Assembler code created with the ASM statement. You can reference LOCAL, STATIC, and GLOBAL variables by name by simply using the name as an operand of the assembler opcode. That isn't possible with INSTANCE and THREADED variables, as their access requires multiple operations best handled by higher level PowerBASIC code. You can also reference procedure parameters by name, though you must differentiate between parameters passed by reference ( ), and those passed by value ( ). Any variable referenced in an assembly-language statement must be defined prior
Maybe an array element referenced by subscript is not eligible for direct use?
Neil,
there are shortcuts that can be used but the following program shows you in seperate steps what you need to do.
Code:
'PBCC 5.01 program
#DIM ALL
#REGISTER NONE 'advise you stop compiler using register variables while you experiment with ASM, it can cause confusion
#INCLUDE "win32api.inc"
FUNCTION PBMAIN () AS LONG
LOCAL ArrayAddress, FirstIndexLimit, SecondIndexLimit, FirstIndex, SecondIndex AS LONG
LOCAL BasicAnswer, AsmAnswer AS LONG
FirstIndexLimit = 162
SecondIndexLimit = 49
DIM n(FirstIndexLimit,SecondIndexLimit) AS LONG
'Fill array with test data
FOR FirstIndex = 0 TO FirstIndexLimit
FOR SecondIndex = 0 TO SecondIndexLimit
n(FirstIndex,SecondIndex) = FirstIndex * 1000 + SecondIndex
NEXT
NEXT
'set the required element to look up
FirstIndex = 100
SecondIndex = 20
'First, do it the easy way with BASIC
BasicAnswer = n(FirstIndex,SecondIndex)
PRINT "BasicAnswer=";BasicAnswer
'now do it the complicated way, with ASM
ArrayAddress = VARPTR (n(0,0)) 'get the address of where BASIC has put the first array element
!mov eax, FirstIndexLimit 'get the size of the first array dimension
!add eax,1 'add 1 because we have zero based arrays
!imul eax,SecondIndex 'to get how many items to skip for each member of this dimension
!add eax,FirstIndex 'add the offset into the next dimension
!imul eax,4 'there are 4 bytes per element
!add eax, ArrayAddress 'add the start address of the data
!mov eax,[eax] 'get the long pointed to by eax into eax, (look up the data from the address we just calculated).
!mov AsmAnswer, eax 'store the result somewhere BASIC can get it
PRINT " AsmAnswer=";AsmAnswer
WAITKEY$
END FUNCTION
Neil,
accessing a single variable in ASM is easy but accessing an element of an array involves calculating where that element is in the array and is a lot more complicated as it depends on the number of dimensions in the array and the sizes of those dimensions and the size of the element.
[Unsnipped bits]
DIM n(162,49) AS LOCAL LONG
LOCAL a,b,c,d,e,f,g,sc,bsc AS LONG
and a,b,c,d,e,f and g are not out of scope. Error is
Code:
PowerBASIC Console Compiler
PB/CC Version 5.01
Copyright (c) 1998-2009 PowerBasic Inc.
Venice, Florida USA
All Rights Reserved
Error 497 in C:\DOCUME~1\ADMINI~1\Desktop\assemb\phase-1.bas(91:001): Assembler syntax error
Line 91: !add eax,n(g,a)
==============================
Compile failed at 00:19:50 on 16/07/2009
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Leave a comment: