I am using Pharo Smalltalk 2.0. I need to convert a float into a ByteArray. There seems to be no method to do this, is there a roundabout way of doing it?
For instance, 1 asFloat asByteArray would be perfect.
Context: I'm trying to send binary data through websocket using the Zinc Websocket package.
A Float already is a variable class, i.e. a little bit similar to an array:
3.14. "=> 3.14"
3.14 size. "=> 2"
3.14 at: 1. "=> 1074339512"
3.14 at: 2. "=> 1374389535"
You can also modify it:
| f |
f := 3.14.
f at: 1 put: 10000.
f. "=> 2.1220636948306e-310"
With that in mind, you now can handle those two integers.
However, Pharo 2.0 typically comes with Fuel pre-installed,
and it already contains means to serialize a float:
ByteArray streamContents: [ :s |
FLEncoder on: s globalEnvironment: Dictionary new do: [ :e |
3.14 serializeOn: e ]] "=> #[64 9 30 184 81 235 133 31]"
Probably, you want to use the Fuel serializing altogether, if you have Pharo or
Squeak on both ends.
If you are on i386 CPU, you can do it with native boost
(ByteArray new: 8) nbFloat64AtOffset: 0 put: Float pi; yourself
Note that byte order is littleEndian in this case.
Otherwise, you have those platform independent access:
(ByteArray new: 8) doubleAt: 1 put: Float pi bigEndian: true ; yourself
Note the difference with 0-based index for first case, and 1-based for second case.
Related
I'm starting to study assembly for PIC18f4550 and I've been trying to do some activities and I don't know how to solve it. According to the activity, Using MPLABX, I'm supposed to sum 2 16bit variables and store the result on a third 16 bit variable.
I was able to sum and store the result on the third variable but I have no idea how to declare these variables in 16bit.
; TODO INSERT CONFIG CODE HERE USING CONFIG BITS GENERATOR
INCLUDE
RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program
; TODO ADD INTERRUPTS HERE IF USED
MAIN_PROG CODE ; let linker place main program
START
clrw ;clear the w register
num1 equ 00000 ;declares 3 variables and their initial values
num2 equ 00001
result equ 00002
movlw H'4F'
movwf num1
movlw H'8A'
movwf num2
movf num1,W ;moves num1 value to w register
addwf num2,W ;sums num2 and w and stores it in w itself
movwf resultado ;moves w to the result register
END
I need to check if my code is actually correct (Im totally new on assembly) and how to declare these 3 variables in 16bit format. Thanks in advance!
The PIC18 is a 8 bit controller. If you want to add two 16 bit variables you had to do it byte by byte.
Maybe you don't want to work with an absolue address and work with the linker:
udata_acs H'000'
num1_LSB RES 1 ;reserve one byte on the access bank
num1_MSB RES 1 ;
You also could reserve two bytes for a name:
udata_acs H'000'
num1 RES 2 ;reserve two bytes on the access bank
Know you could access the second byte with :
movwf num1+1
And always remember to check the carry bit to get the MSB of an addition.
Question:
Is there/What is the Perl6 counterpart of Powershells get-member to "analyse" the attributes of a variable?
Explanation:
In Perl 6 you can get properties/attributes of a variable, e.g.:
my $num=16.03;
say $num.numerator; # output: 1603
say $num.denominator; # output: 100
say $num.nude; # output: (1603 100)
say $num.WHAT; # output: (Rat)
How can I find out, which attributes/properties (numerator etc.) and methods/functions (WHAT) a variable has?
In Powershell I would pipe the variable to get-member, like:
$num | get-member and would get all properties and function displayed.
The best way would be to consult the docs for whatever type .WHAT told you, e.g. https://docs.perl6.org/type/Rat for Rat.
If you must have it programmatically, you can ask the object for its methods with .^methods.
> my $num = 16.03
16.03
> $num.^methods
(Rat FatRat Range atanh Bridge sign sqrt asech sin tan atan2 acosech truncate
asinh narrow base floor abs conj acosh pred new asec cosec acotan cosh ceiling
nude acos acosec sech unpolar log exp roots cotan norm sinh tanh acotanh Int
Num Real sec asin rand polymod log10 cos round REDUCE-ME succ base-repeating
cis cosech isNaN Complex cotanh atan perl WHICH Str ACCEPTS gist Bool Numeric
DUMP numerator denominator)
You can similarly see the attributes ('properties') with .^attributes, but any that you should access will have accessor methods anyway, so you shouldn't really need to do that.
Is there a predefined way to compute the modulo of two integers in Clean?
StdOverloaded defines the (mod) typeclass, but StdInt does not contain an instance of it, and StdEnv does not either anywhere else. I have seen a language overview about Clean version 2.0, which mentions StdInt's mod instance, but in 2.4, it is definitely missing.
StdInt delivers another alternative: it's called rem. Works just like the old fashioned mod function, but also works fine with signed integers.
10 rem 7 // 3
10 rem -7 // 3
-10 rem 7 // -3
-10 rem -7 //-3
In the latest stable release (Clean 3.0) , it is possible to use "rem" by just importing StdEnv instance.
This question already has answers here:
Solution needed for building a static IDT and GDT at assemble/compile/link time
(1 answer)
How to do computations with addresses at compile/linking time?
(2 answers)
Closed 5 days ago.
I'm working on a project that has tight boot time requirements. The targeted architecture is an IA-32 based processor running in 32 bit protected mode. One of the areas identified that can be improved is that the current system dynamically initializes the processor's IDT (interrupt descriptor table). Since we don't have any plug-and-play devices and the system is relatively static, I want to be able to use a statically built IDT.
However, this proving to be troublesome for the IA-32 arch since the 8 byte interrupt gate descriptors splits the ISR address. The low 16 bits of the ISR appear in the first 2 bytes of the descriptor, some other bits fill in the next 4 bytes, and then finally the last 16 bits of the ISR appear in the last 2 bytes.
I wanted to use a const array to define the IDT and then simply point the IDT register at it like so:
typedef struct s_myIdt {
unsigned short isrLobits;
unsigned short segSelector;
unsigned short otherBits;
unsigned short isrHibits;
} myIdtStruct;
myIdtStruct myIdt[256] = {
{ (unsigned short)myIsr0, 1, 2, (unsigned short)(myIsr0 >> 16)},
{ (unsigned short)myIsr1, 1, 2, (unsigned short)(myIsr1 >> 16)},
etc.
Obviously this won't work as it is illegal to do this in C because myIsr is not constant. Its value is resolved by the linker (which can do only a limited amount of math) and not by the compiler.
Any recommendations or other ideas on how to do this?
You ran into a well known x86 wart. I don't believe the linker can stuff the address of your isr routines in the swizzled form expected by the IDT entry.
If you are feeling ambitious, you could create an IDT builder script that does something like this (Linux based) approach. I haven't tested this scheme and it probably qualifies as a nasty hack anyway, so tread carefully.
Step 1: Write a script to run 'nm' and capture the stdout.
Step 2: In your script, parse the nm output to get the memory address of all your interrupt service routines.
Step 3: Output a binary file, 'idt.bin' that has the IDT bytes all setup and ready for the LIDT instruction. Your script obviously outputs the isr addresses in the correct swizzled form.
Step 4: Convert his raw binary into an elf section with objcopy:
objcopy -I binary -O elf32-i386 idt.bin idt.elf
Step 5: Now idt.elf file has your IDT binary with the symbol something like this:
> nm idt.elf
000000000000000a D _binary_idt_bin_end
000000000000000a A _binary_idt_bin_size
0000000000000000 D _binary_idt_bin_start
Step 6: relink your binary including idt.elf. In your assembly stubs and linker scripts, you can refer to symbol _binary_idt_bin_start as the base of the IDT. For example, your linker script can place the symbol _binary_idt_bin_start at any address you like.
Be careful that relinking with the IDT section doesn't move anyting else in your binary, e.g. your isr routines. Manage this in your linker script (.ld file) by puting the IDT into it's own dedicated section.
---EDIT---
From comments, there seems to be confusion about the problem. The 32-bit x86 IDT expects the address of the interrupt service routine to be split into two different 16-bit words, like so:
31 16 15 0
+---------------+---------------+
| Address 31-16 | |
+---------------+---------------+
| | Address 15-0 |
+---------------+---------------+
A linker is thus unable to plug-in the ISR address as a normal relocation. So, at boot time, software must construct this split format, which slows boot time.
I tried carl function
http://www.rebol.com/article/0281.html
with 155 Mo it works.
Then I tested with 7 Go it fails without saying the limit.
Why is there a limit I can't see anything in code that puts a limit.
There's no error message
>> copy-file to-rebol-file "D:\#mirror_ftp\cpmove.tar" to-rebol-file "D:\#mirror_ftp\testcopy.tar"
0:00
== none
>>
REBOL uses 32-bit signed integers, so it can't read files bigger than 2147483647 bytes (2^31-1) which is roughly 2GB. REBOL3 uses 64-bit integers, so won't have such limitation.