Is there a proper way to exit this ASM block? I'm JMP-ing to an empty line because I can't see any other way to do it. Is there a "quit" command which I could use in place of "jmp Fin"?
Dim bytvar As Byte
Dim bstatus As Byte
Do
Input "Enter a byte value (0 to quit): ", bytvar
If bytvar = 0 Then
Exit Do
End If
' If bytvar = 1, then Status = 1, else Status = 0
ASM
cmpb [bytvar], 1
jne Stat0
movb [bstatus], 1
jmp Fin
Stat0: movb [bstatus], 0
Fin:
End Asm
Print "Status = "; bstatus
Loop
Sleep
Any "exit asm" command would just be a high-level syntactic sugar for the exact same jump. Since the goal of ASM is to allow low-level assembly code directly in your program, I would assume any user of this facility would want to do their own jumps explicitly. That's the point of ASM after all.
caseih wrote:Any "exit asm" command would just be a high-level syntactic sugar for the exact same jump. Since the goal of ASM is to allow low-level assembly code directly in your program, I would assume any user of this facility would want to do their own jumps explicitly. That's the point of ASM after all.
Well, I explicitly want to JMP to the end of the ASM. ;-) Jumping to an empty line seems inelegant, if not illogical.
I notice that ASM has a "leave" instruction, but that incorporates a RET. In any case, if there is a LEAVE pseudo-instruction or directive or whatever it is called, then I see no reason why there couldn't be an EXIT ASM.
Well good news, then. If jmp is what you explicitly want, then you explicitly type it! You seem to prefer an implicit jump, however. Just to be pedantic. ;)
While it's true that assemblers heavily rely on macros to add syntactic sugar, in this case your reference to "leave" is an actual opcode, if I'm not mistaken, which cleans up the stack frame and jumps to the caller. It's real instruction, not a psuedo instruction.
I'm not sure exactly how much work FB puts into the ASM block, but traditionally the contents of the block are passed more or less directly to the assembler. So if you wanted an EXIT ASM statement it would have to be something that was part of and provided by the assembler, unless I'm very much mistaken. That could be the reason why no one ever thought of implementing that before.
Dim bytvar As Byte
Dim bstatus As Byte
Do
Input "Enter a byte value (0 to quit): ", bytvar
If bytvar = 0 Then
Exit Do
End If
' If bytvar = 1, then Status = 1, else Status = 0
ASM
cmpb [bytvar], 1
jne Stat0
movb [bstatus], 1
jmp Fin
Stat0: movb [bstatus], 0
Fin: nop
End Asm
Print "Status = "; bstatus
Loop
Sleep
' Assembly language function to reverse the endian-ness of a block of 32-bit dwords
Function EndianRev32 naked ( ByRef srcNums As uLong, ByRef destNums As uLong, ByVal elements as uLong ) As uLong
ASM
push esi
push edi
mov ecx, [esp+8+12] 'elements
mov esi, [esp+8+4] 'srcNums
mov edi, [esp+8+8] 'destNums
push ecx
L1: lodsd
bswap eax
stosd
dec ecx
jg L1
pop eax ' return #elements
pop edi
pop esi
' mov [function], ecx won't work in naked functions
ret 12 ' return with three ulong arguments
End ASM
End Function
dim s(10) as ulong=>{100, 101, 102, 103, 104, 105, 106, 107, 108, 109}
dim d(10) as ulong
Print "Swapping src->dest:"
Print EndianRev32(s(0), d(0), 10);" elements swapped"
For ct As long=0 To 9
Print ct, hex(d(ct))
Next
Print "Swapping dest->dest:"
Print EndianRev32(d(0), d(0), 10);" elements swapped"
For ct As long=0 To 9
Print ct, hex(d(ct))
Next
sleep
caseih wrote:traditionally the contents of the block are passed more or less directly to the assembler