Host introspection: Difference between revisions

m
m (added missing </lang>)
m (→‎{{header|Wren}}: Minor tidy)
 
(24 intermediate revisions by 12 users not shown)
Line 1:
{{task|Programming environment operations}}
{{omit from|6502 Assembly|without 16 bit data registers you can't prove this without already knowing the answer}}
{{omit from|Brlcad}}
{{omit from|E}}
Line 12 ⟶ 13:
 
See also: [[Variable size/Get]]
=={{header|68000 Assembly}}==
It's not possible to get the word size without knowing it in advance. But the 68000's big-endian nature can easily be proven even if the programmer didn't know that it was big-endian already.
Code is called as a subroutine, i.e. <code>JSR TestEndianness</code>. Hardware-specific print routines are unimplemented.
<syntaxhighlight lang="68000devpac">TestEndianness:
LEA UserRam,A0
MOVE.L #$0000FFFF,(A0)
MOVE.B (A0),D0 ;read the 0th byte stored
BEQ isBigEndian ;if this was little endian, the bytes would be stored FF FF 00 00
;must have been little-endian. Spoiler alert: execution will never reach here
LEA LittleEndianMessage,A3
JSR PrintString
rts
isBigEndian:
LEA BigEndianMessage,A3
JSR PrintString
rts
 
BigEndianMessage:
DC.B "BIG-ENDIAN",0
EVEN
LittleEndianMessage:
DC.B "LITTLE-ENDIAN",0
EVEN</syntaxhighlight>
=={{header|8086 Assembly}}==
As with [[68000 Assembly]], there's no way to "prove" the word size without knowing it in advance. But endianness can still be tested for quite easily.
<syntaxhighlight lang="asm"> .model small
.stack 1024
 
.data
 
UserRam BYTE 256 DUP (0)
 
.code
start:
 
mov ax,@data ;assembler calculates this offset for us
mov ds,ax ;the 8086 can only load segment registers from other registers, not directly from immediate values.
 
mov ax,@code
mov es,ax
 
mov ax,3422h
mov word ptr [ds:UserRam],ax
mov bl, byte ptr [ds:UserRam]
call doMonitor ;a routine that prints the contents of
;the 8086's registers to the screen
 
mov ax,4C00h
int 21h ;return to MS-DOS
 
end start</syntaxhighlight>
 
If the 8086 is little-endian, BX will equal 0022, since we loaded the low byte of UserRam into BL (the low half of BX). If it's big-endian, BX will equal 0034.
 
{{out}}
<pre>
Monitor tools created by Keith of Chibiakumas
AX:3422 BX:0022 CX:00FF DX:0192
F :------I--------- IP:0018
SP:03FA BP:091C DI:0400 SI:0388
CS:01A2 DS:01EC ES:01A2 SS:0425
</pre>
 
From this we conclude that the 8086 is indeed a little-endian CPU.
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC Main()
PrintE("All Atari 8-bit computers use little-endian word of 16-bits size.")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Host_introspection.png Screenshot from Atari 8-bit computer]
<pre>
All Atari 8-bit computers use little-endian word of 16-bits size.
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with System; use System;
 
Line 21 ⟶ 97:
Put_Line ("Word size" & Integer'Image (Word_Size));
Put_Line ("Endianness " & Bit_Order'Image (Default_Bit_Order));
end Host_Introspection;</langsyntaxhighlight>
 
{{out|Sample output on a Pentium machine}}
Line 34 ⟶ 110:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
<langsyntaxhighlight lang="algol68">INT max abs bit = ABS(BIN 1 SHL 1)-1;
INT bits per char = ENTIER (ln(max abs char+1)/ln(max abs bit+1));
INT bits per int = ENTIER (1+ln(max int+1.0)/ln(max abs bit+1));
Line 57 ⟶ 133:
int byte order +:= REPR(abcdi OVER (max abs bit+1) ** shift MOD (max abs char+1))
OD;
printf(($"int byte order: "g,", Hex:",16r8dl$,int byte order, BIN abcdi))</langsyntaxhighlight>
{{out}} (Intel i686):
<pre>
Line 84 ⟶ 160:
 
=={{header|Applesoft BASIC}}==
<langsyntaxhighlight ApplesoftBasiclang="applesoftbasic">1 DATA248,169,153,24,105,1,48
2 DATA6,24,251,144,2,251,56
3 DATA216,105,0,133,251,96
Line 95 ⟶ 171:
10 IF M THEN PRINT M$
11 PRINT "ENDIANNESS: ";
12 PRINT "LITTLE-ENDIAN"</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
The word size of the ARM is 32-bit, which can't really be proven without knowing it ahead of time.
 
The ARM CPU's endianness can be set to either little-endian or big-endian. Not all ARM CPUs have this feature, but this test will work regardless of whether the endian switch features exist on any particular model or not. The easiest way to test endianness is to write a word to RAM, then read the 0th byte from that memory location and see what it is. (The example below uses VASM syntax.)
 
<syntaxhighlight lang="arm assembly">EndianTest:
mov r0,#0xFF
mov r1,#0x02000000 ;an arbitrary memory location on the Game Boy Advance.
;(The GBA is always little-endian but this test doesn't use that knowledge to prove it.)
str r0,[r1] ;on a little-endian CPU a hexdump of 0x02000000 would be: FF 00 00 00
;on a big-endian CPU it would be: 00 00 00 FF
ldrB r0,[r1] ;load just the byte at 0x02000000. If the machine is big-endian this will load 00; if little-endian, 0xFF.
cmp r0,#0
beq isBigEndian
;else, do whatever is needed to display "little-endian" to the screen. This part isn't implemented.</syntaxhighlight>
=={{header|Babel}}==
<langsyntaxhighlight lang="babel">main :
{ "Word size: " << msize 3 shl %d << " bits" cr <<
"Endianness: " << { endian } { "little" } { "big" } ifte cr << }</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> DIM P% 8
!P% = -1
I% = 0 : REPEAT I% += 1 : UNTIL P%?I%=0
Line 109 ⟶ 200:
!P% = 1
IF P%?0 = 1 THEN PRINT "Little-endian"
IF P%?(I%-1) = 1 THEN PRINT "Big-endian"</langsyntaxhighlight>
The 'word size' is reported as the number of bytes accessed by the ! indirection operator, which is 4 in all current versions of BBC BASIC.
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stddef.h> /* for size_t */
#include <limits.h> /* for CHAR_BIT */
Line 134 ⟶ 225:
printf("big endian\n");
return 0;
}</langsyntaxhighlight>
 
On POSIX-compatible systems, the following also tests the endianness (this makes use of the fact that network order is big endian):
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <arpa/inet.h>
 
Line 146 ⟶ 237:
else
printf("little endian\n");
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">static void Main()
{
Console.WriteLine("Word size = {0} bytes,",sizeof(int));
Line 157 ⟶ 248:
else
Console.WriteLine("Big-endian.");
}</langsyntaxhighlight>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <bit>
#include <iostream>
 
int main()
{
std::cout << "int is " << sizeof(int) << " bytes\n";
std::cout << "a pointer is " << sizeof(int*) << " bytes\n\n";
 
if (std::endian::native == std::endian::big)
{
std::cout << "platform is big-endian\n";
}
else
{
std::cout << "host is little-endian\n";
}
}</syntaxhighlight>
{{out}}
<pre>
int is 4 bytes
a pointer is 8 bytes
 
host is little-endian
</pre>
 
=={{header|Caché ObjectScript}}==
Line 168 ⟶ 285:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(println "word size: " (System/getProperty "sun.arch.data.model"))
(println "endianness: " (System/getProperty "sun.cpu.endian"))</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 176 ⟶ 293:
 
The [http://www.lispworks.com/documentation/HyperSpec/Body/c_enviro.htm Environment] has some implementation-specific functions that might provide a good hint, e.g.,
<langsyntaxhighlight lang="lisp">(machine-type) ;; => "X86-64" on SBCL here</langsyntaxhighlight>
 
The [http://www.cliki.net/features *features*] list also provides useful information, e.g., some compilers declare :LITTLE-ENDIAN there.
Line 183 ⟶ 300:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.system;
 
writeln("Word size = ", size_t.sizeof * 8, " bits.");
writeln(endian == Endian.littleEndian ? "Little" : "Big", " endian.");
}</langsyntaxhighlight>
{{out}}
<pre>Word size = 64 bits.
Line 194 ⟶ 311:
 
=={{header|Delphi}}==
<langsyntaxhighlight Delphilang="delphi">program HostIntrospection ;
 
{$APPTYPE CONSOLE}
Line 203 ⟶ 320:
Writeln('word size: ', SizeOf(Integer));
Writeln('endianness: little endian'); // Windows is always little endian
end.</langsyntaxhighlight>
 
=={{header|Erlang}}==
To find the word size:
<langsyntaxhighlight lang="erlang">1> erlang:system_info(wordsize).
4</langsyntaxhighlight>
 
In the case of endianness, Erlang's bit syntax by default has a 'native' option which lets you use what is supported natively.
Line 214 ⟶ 331:
However, one could write one by using bit syntax, setting endianness and then comparing to the native format:
 
<langsyntaxhighlight lang="erlang">1> <<1:4/native-unit:8>>.
<<1,0,0,0>>
2> <<1:4/big-unit:8>>
<<0,0,0,1>>
3> <<1:4/little-unit:8>>.
<<1,0,0,0>></langsyntaxhighlight>
 
And so the following function would output endianness:
 
<langsyntaxhighlight lang="erlang">endianness() when <<1:4/native-unit:8>> =:= <<1:4/big-unit:8>> -> big;
endianness() -> little.</langsyntaxhighlight>
 
=={{header|F_Sharp|F#}}==
A lot of research before I finally came up with an answer to this that isn't dependent on the machine it was compiled on. Works on Win32 machines only (obviously, due to the interop). I think that strictly speaking, I should be double checking the OS version before making the call to wow64Process, but I'm not worrying about it.
<syntaxhighlight lang="fsharp">open System
open System.Runtime.InteropServices
open System.Diagnostics
 
[<DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)>]
extern bool IsWow64Process(nativeint hProcess, bool &wow64Process);
 
let answerHostInfo =
let Is64Bit() =
let mutable f64Bit = false;
IsWow64Process(Process.GetCurrentProcess().Handle, &f64Bit) |> ignore
f64Bit
let IsLittleEndian() = BitConverter.IsLittleEndian
(IsLittleEndian(), Is64Bit())</syntaxhighlight>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: alien.c-types alien.data io layouts ;
"Word size: " write cell 8 * .
"Endianness: " write little-endian? "little" "big" ? print</langsyntaxhighlight>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: endian
cr 1 cells . ." address units per cell"
s" ADDRESS-UNIT-BITS" environment? if cr . ." bits per address unit" then
cr 1 here ! here c@ if ." little" else ." big" then ." endian" ;</langsyntaxhighlight>
This relies on '''c@''' being a byte fetch (4 chars = 1 cells). Although it is on most architectures, ANS Forth only guarantees that 1 chars <= 1 cells. Some Forths like OpenFirmware have explicitly sized fetches, like b@.
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later< 2018}}
<langsyntaxhighlight lang="fortran"> integer :: i
character(len=1) :: c(20)
equivalence (c, i)
Line 252 ⟶ 386:
ELSE
WRITE(*,*) "Little Endian"
END IF</langsyntaxhighlight>
{{works with|Fortran| 77 and later}}
<syntaxhighlight lang="fortran">
PROGRAM endianness
IMPLICIT NONE
INTEGER(KIND=4) :: i = 1
 
!ISHFT(INTEGER, SHIFT) : Left shift if SHIFT > 0
!ISHFT(INTEGER, SHIFT) : Right shift if SHIFT < 0
IF (ISHFT(i,1) .EQ. 0) THEN
WRITE(*,FMT='(A)') 'Architechture is Big Endian'
ELSE
WRITE(*,FMT='(A)') 'Architecture is Little Endian'
END IF
 
RETURN
 
STOP
END PROGRAM endianness
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64 (so little endian, 8 byte word size, expected)
 
' uses intrinsic defines, set by the compiler
Line 271 ⟶ 424:
#EndIf
 
Sleep</langsyntaxhighlight>
 
{{out}}
Line 280 ⟶ 433:
 
=={{header|Frink}}==
<langsyntaxhighlight lang="frink">
println["Word size: " + callJava["java.lang.System", "getProperty", "sun.arch.data.model"]]
println["Endianness: " + callJava["java.lang.System", "getProperty", "sun.cpu.endian"]]
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
A lot of research before I finally came up with an answer to this that isn't dependent on the machine it was compiled on. Works on Win32 machines only (obviously, due to the interop). I think that strictly speaking, I should be double checking the OS version before making the call to wow64Process, but I'm not worrying about it.
<lang fsharp>open System
open System.Runtime.InteropServices
open System.Diagnostics
 
[<DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)>]
extern bool IsWow64Process(nativeint hProcess, bool &wow64Process);
 
let answerHostInfo =
let Is64Bit() =
let mutable f64Bit = false;
IsWow64Process(Process.GetCurrentProcess().Handle, &f64Bit) |> ignore
f64Bit
let IsLittleEndian() = BitConverter.IsLittleEndian
(IsLittleEndian(), Is64Bit())</lang>
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 372 ⟶ 509:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 405 ⟶ 542:
</pre>
Alternative technique:
<langsyntaxhighlight lang="go">package main
 
import (
Line 421 ⟶ 558:
fmt.Println(f.FileHeader.ByteOrder)
f.Close()
}</langsyntaxhighlight>
{{out}}
<pre>
Line 429 ⟶ 566:
=={{header|Groovy}}==
Solution follows [[Java]]:
<langsyntaxhighlight lang="groovy">println "word size: ${System.getProperty('sun.arch.data.model')}"
println "endianness: ${System.getProperty('sun.cpu.endian')}"</langsyntaxhighlight>
 
{{out}}
Line 437 ⟶ 574:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.Bits
import ADNS.Endian -- http://hackage.haskell.org/package/hsdns
 
Line 444 ⟶ 581:
putStrLn $ "Endianness: " ++ show endian
where
bitsize = show $ bitSize (undefined :: Int)</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
 
<langsyntaxhighlight lang="unicon">procedure main()
write(if 0 = ishift(1,-1) then "little" else "big"," endian")
if match("flags",line := !open("/proc/cpuinfo")) then # Unix-like only
write(if find(" lm ",line) then 64 else 32," bits per word")
else write("Cannot determine word size.")
end</langsyntaxhighlight>
 
Sample run:
Line 466 ⟶ 603:
=={{header|J}}==
 
<langsyntaxhighlight lang="j"> IF64 {32 64
64</langsyntaxhighlight>
 
This returns <code>32</code> in 32 bit J.
 
This value could also be calculated, exercising left shift of bits in a 2s complement fixed width integer:<syntaxhighlight lang="j"> 2+2^.>./1&(33 b.)^:a:1
64</syntaxhighlight>
 
Note that this mechanism is testing the interpreter, and not the OS or Hardware. (Though, of course, you cannot run a 64 bit interpreter on a machine that does not support it.)
Line 475 ⟶ 615:
That said, this does not deal with endianness. For the most part, J programs do not need to know their own endianness. When converting to and from binary format you can specify "native", "little endian" and "big endian", and it's rare that you have an interface which would need anything else. That said, you can inspect the binary representation of a simple constant:
 
<langsyntaxhighlight lang="j"> ":&> (|: 32 64 ;"0 big`little) {"_1~ 2 2 #: 16b_e0 + a. i. 0 { 3!:1 ''
64
little</langsyntaxhighlight>
 
=={{header|Java}}==
Line 484 ⟶ 624:
{{works with|Java|1.4}}
 
<langsyntaxhighlight lang="java">import java.nio.ByteOrder;
 
public class ShowByteOrder {
Line 491 ⟶ 631:
System.out.println(ByteOrder.nativeOrder());
}
}</langsyntaxhighlight>
 
Some JVMs also have system properties for the word size and byte order.
 
<langsyntaxhighlight lang="java">System.out.println("word size: "+System.getProperty("sun.arch.data.model"));
System.out.println("endianness: "+System.getProperty("sun.cpu.endian"));</langsyntaxhighlight>
 
=={{header|Julia}}==
<code>Julia</code> creates <code>ENDIAN_BOM</code> a 32 bit unsigned integer out of an array of 4 8 bit unsigned integers to serve as an endianness marker.
<syntaxhighlight lang="julia">
<lang Julia>
print("This host's word size is ", WORD_SIZE, ".")
if ENDIAN_BOM == 0x04030201
Line 509 ⟶ 649:
println("ENDIAN_BOM = ", ENDIAN_BOM, ", which is confusing")
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 518 ⟶ 658:
=={{header|Kotlin}}==
The following is not guaranteed to work on all JVMs but is working fine on my x64 Windows 10 machine:
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun main(args: Array<String>) {
println("Word size : ${System.getProperty("sun.arch.data.model")} bits")
println("Endianness: ${System.getProperty("sun.cpu.endian")}-endian")
}</langsyntaxhighlight>
 
{{out}}
Line 530 ⟶ 670:
Endianness: little-endian
</pre>
 
=={{header|Lua}}==
Pure/native Lua can't do this (and essentially doesn't care). However, Lua is often used in a scripting environment, where such issues may be important, and any needed support would be expected to be provided by the host or some other external library. Here using ffi:
<syntaxhighlight lang="lua">ffi = require("ffi")
print("size of int (in bytes): " .. ffi.sizeof(ffi.new("int")))
print("size of pointer (in bytes): " .. ffi.sizeof(ffi.new("int*")))
print((ffi.abi("le") and "little" or "big") .. " endian")</syntaxhighlight>
{{out}}
<pre>size of int (in bytes): 4
size of pointer (in bytes): 8
little endian</pre>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckIt {
\\ Always run in Little-endian, 32 bits (in Wow64 in 64 bit os)
Line 561 ⟶ 713:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|MACRO-10}}==
<syntaxhighlight lang="macro-10">
title Host Introspection
subttl PDP-10 assembly (MACRO-10 on TOPS-20). KJX 2022.
search monsym,macsym
 
comment \
The wordsize is detected by putting 1 into a re-
gister, counting the leading zeros (resulting in
wordsize-1) and adding 1 to the result.
 
Endianness doesn't really apply, as the PDP-10 is
a 36bit word-adressable computer, and the handling
of characters is peculiar enough that it would get
out of hand if I'd dive into the details here.
\
 
a=:1 ;Define three accumulators.
b=:2
c=:3
 
start:: reset% ;Initialize process.
 
movei a,1 ;Set A to 1.
jffo a,.+1 ;B = leading zeros of A.
aos b ;Add 1 to B. -> wordsize.
 
movei a,.priou ;Print B on standard output
movei c,^d10 ;in base 10.
nout%
jfcl
 
haltf% ;Halt program.
jrst start ;Allow continue-command.
 
end start
</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">If[$ByteOrdering > 0, Print["Big endian"], Print["Little endian" ]]
$SystemWordLength "bits"</langsyntaxhighlight>
 
{{out}} x86
Line 576 ⟶ 767:
The concept of "word size" is not meaningful in Matlab and Octave, uint64 is also available on 32bit-platforms, and there are no pointers. Endianity can be tested with the function below:
 
<langsyntaxhighlight MATLABlang="matlab"> function [endian]=endian()
fid=tmpfile();
fwrite(fid,1:8,'uint8');
Line 593 ⟶ 784:
else endian='little';
end;
</syntaxhighlight>
</lang>
 
{{out}}
Line 601 ⟶ 792:
endian = little</pre>
 
=={{header|MIPS Assembly}}==
This uses Keith S.'s tutorial at [https://www.chibialiens.com/mips/ Chibialiens.com] to print memory and show register contents.
As I've come to find out, MIPS is a bi-endian architecture (meaning its endianness is implementation-defined rather than a constant trait of the CPU.) In particular, the PlayStation 1 is little-endian, and the Nintendo 64 is big-endian. This can be proven with the test below. (Hardware-specific routines <code>MonitorA0A1RAPC</code> and <code>MemDump</code> are omitted just to keep things brief.)
 
<syntaxhighlight lang="mips"> jal Cls ;Zero Graphics cursor position
nop ;on the PlayStation, the instruction AFTER a branch gets executed BEFORE the branch actually occurs.
;The Nintendo 64 didn't have this "feature" but for compatibility's sake
; it's staying in regardless of which version of the code I'm using.
 
la a2,TestData ;Load address of TestData
lw a0,(a2) ;Load Word into A0 from address in A2
addiu a2,4 ;pointer arithmetic to load the next word.
lw a1,(a2)
move t6,ra
jal MonitorA0A1RAPC
nop
li t6,2 ;Line Count - 2 lines = 16 bytes
jal MemDump ;Dump Ram to screen
nop
halt:
j halt ;loop forever
nop
 
 
 
 
TestData:
.byte 0xF3,0xF2,0xF1,0xF0 ;this will load as F0F1F2F3 on little-endian machines, and as-is on big-endian
.word 0xF0F1F2F3 ;this will load as F0F1F2F3 regardless of endianness.
</syntaxhighlight>
{{out}}
Register Dump of PlayStation 1:
<pre>a0:F0F1F2F3 a1:F0F1F2F3</pre>
 
Register Dump of Nintendo 64:
<pre>a0:F3F2F1F0 a1:F0F1F2F3</pre>
 
It also seems the registers are 32-bit even on the N64. I wouldn't have expected that to be honest...
 
=={{header|Modula-3}}==
<langsyntaxhighlight lang="modula3">MODULE Host EXPORTS Main;
 
IMPORT IO, Fmt, Word, Swap;
Line 614 ⟶ 848:
IO.Put("Endianness: Little\n");
END;
END Host.</langsyntaxhighlight>
 
{{out}} (on an x86):
Line 627 ⟶ 861:
C support file, host-introspection.c
 
<langsyntaxhighlight Clang="c">/* Return wordsize to Neko */
/* From Rosetta Code, C entry, with Neko marshalling */
 
Line 642 ⟶ 876:
}
/* Expose symbol to Neko loader */
DEFINE_PRIM(wordsize, 0);</langsyntaxhighlight>
 
Neko caller, host-introspection.neko
 
<syntaxhighlight lang="actionscript">/**
<lang ActionScript>/**
Host introspection, in Neko
*/
Line 661 ⟶ 895:
 
var wordsize = $loader.loadprim("native@wordsize", 0)
$print("wordsize: ", wordsize(), " bits\n")</langsyntaxhighlight>
 
{{out}}
Line 674 ⟶ 908:
{{trans|Java}}
NetRexx can access this information from the [[Java]] virtual machine in the same way as the [[#Java|Java]] sample above.
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
 
Line 682 ⟶ 916:
say ' word size:' wordSize
say 'endianness:' endian
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
In Nim, "int" type has the size of the word. So, to find the word size in bits, just multiply the "int" size in bytes by eight.
<lang nim>import math
<syntaxhighlight lang="nim">echo cpuEndian
echo round(log2(floatsizeof(int.high))) +* 18</langsyntaxhighlight>
 
=={{header|Objective-C}}==
Endianness:
<langsyntaxhighlight lang="objc">switch (NSHostByteOrder()) {
case NS_BigEndian:
NSLog(@"%@", @"Big Endian");
Line 701 ⟶ 935:
NSLog(@"%@", @"endianness unknown");
break;
} </langsyntaxhighlight>
 
Architecture:
(works on Mac OS X 10.6+)
<langsyntaxhighlight lang="objc">switch ([NSRunningApplication currentApplication].executableArchitecture) {
case NSBundleExecutableArchitectureI386:
NSLog(@"%@", @"i386 32-bit");
Line 725 ⟶ 959:
NSLog(@"%@", @"Unknown");
break;
}</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">Printf.printf "%d\n" Sys.word_size; (* Print word size *)
Printf.printf "%s\n" Sys.os_type; (* Print operating system *)</langsyntaxhighlight>
 
{{works with|OCaml|4.00+}}
<langsyntaxhighlight lang="ocaml">(* Print endianness *)
Printf.printf "%s\n" (if Sys.big_endian then "big endian" else "little endian");</langsyntaxhighlight>
 
On OCaml 3 and below, there are tricks to get endianness. For example in Linux or Unix variants,
one may use the [http://unixhelp.ed.ac.uk/CGI/man-cgi?uname uname] shell command :
 
<langsyntaxhighlight lang="ocaml">let uname arg =
let arg = if arg = "" then "-" else arg in
let ic = Unix.open_process_in ("uname -" ^ arg) in
Line 746 ⟶ 980:
 
# uname "sm";;
- : string = "Linux i686"</langsyntaxhighlight>
 
In most cases, endianness can be infered from informations given by uname.
Line 752 ⟶ 986:
One may also read files in the /proc directory in order to get informations about the host, only under linux :
 
<langsyntaxhighlight lang="ocaml">(* Reading all the lines from a file.
If the loop is implemented by a recursive auxiliary function, the try...with breaks
tail recursion if not written carefully *)
Line 785 ⟶ 1,019:
"VmallocChunk: 109320 kB"; "HugePages_Total: 0";
"HugePages_Free: 0"; "HugePages_Rsvd: 0";
"HugePages_Surp: 0"; "Hugepagesize: 4096 kB"]</langsyntaxhighlight>
 
Same methods can be used to get the results of commands lshw, dmidecode...
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">program HostIntrospection(output);
begin
writeln('Pointer size: ', SizeOf(Pointer), ' byte, i.e. ', SizeOf(Pointer)*8, ' bit.');
Line 798 ⟶ 1,032:
else
writeln('This host is little endian.');
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 808 ⟶ 1,042:
=={{header|Perl}}==
Most basic example:
<langsyntaxhighlight lang="perl">use Config;
print "UV size: $Config{uvsize}, byte order: $Config{byteorder}\n";</langsyntaxhighlight>
{{out}}
<pre>
Line 816 ⟶ 1,050:
 
More verbose example:
<langsyntaxhighlight lang="perl">use 5.010;
use Config;
my ($size, $order, $end) = @Config{qw(uvsize byteorder)};
Line 824 ⟶ 1,058:
default { $end = 'mixed' }
}
say "UV size: $size, byte order: $order ($end-endian)";</langsyntaxhighlight>
{{out}}
<pre>
Line 835 ⟶ 1,069:
UV size: 8, byte order: 87654321 (big-endian)
</pre>
=={{header|Perl 6}}==
Endian detection translated from C. {{works with|Rakudo|2018.03}}
<lang perl6>use NativeCall;
say $*VM.config<ptr_size>;
my $bytes = nativecast(CArray[uint8], CArray[uint16].new(1));
say $bytes[0] ?? "little-endian" !! "big-endian";</lang>
{{out}}
<pre>8
little-endian</pre>
Note: Rakudo 2018.12 is introducing the endian-sensitive<code>read-int16</code> method,
which makes endian detection a little easier:
<lang perl6>say blob8.new(1,0).read-int16(0) == 1 ?? "little-endian" !! "big-endian"</lang>
 
=={{header|Phix}}==
Note that machine_word() and machine_bits() test the interpreter or compiled executable, rather than the OS or hardware.<br>
Also, all known implementations of Phix are currently little-endian. See also platform(), which yields WINDOWS or /LINUX/JS.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function endianness()
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
atom m4 = allocate(4)
<span style="color: #008080;">function</span> <span style="color: #000000;">endianness</span><span style="color: #0000FF;">()</span>
poke4(m4,#01020304)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
integer b1 = peek1s(m4)
<span style="color: #008080;">return</span> <span style="color: #008000;">"n/a (web browser)"</span>
free(m4)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if b1=#01 then
<span style="color: #004080;">atom</span> <span style="color: #000000;">m4</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
return "big-endian"
<span style="color: #7060A8;">poke4</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#01020304</span><span style="color: #0000FF;">)</span>
elsif b1=#04 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">b1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek1s</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m4</span><span style="color: #0000FF;">)</span>
return "little-endian"
<span style="color: #7060A8;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m4</span><span style="color: #0000FF;">)</span>
else
<span style="color: #008080;">if</span> <span style="color: #000000;">b1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">#01</span> <span style="color: #008080;">then</span>
return "???"
<span style="color: #008080;">return</span> <span style="color: #008000;">"big-endian"</span>
end if
<span style="color: #008080;">elsif</span> <span style="color: #000000;">b1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">#04</span> <span style="color: #008080;">then</span>
end function
<span style="color: #008080;">return</span> <span style="color: #008000;">"little-endian"</span>
 
<span style="color: #008080;">else</span>
printf(1,"Endianness: %s\n",{endianness()})
<span style="color: #008080;">return</span> <span style="color: #008000;">"???"</span>
printf(1,"Word size: %d bytes/%d bits\n",{machine_word(),machine_bits()})</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Endianness: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">endianness</span><span style="color: #0000FF;">()})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Word size: %d bytes/%d bits\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">machine_word</span><span style="color: #0000FF;">(),</span><span style="color: #7060A8;">machine_bits</span><span style="color: #0000FF;">()})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 876 ⟶ 1,104:
Endianness: little-endian
Word size: 8 bytes/64 bits
</pre>
or
<pre>
Endianness: n/a (web browser)
Word size: 4 bytes/32 bits
</pre>
 
Line 883 ⟶ 1,116:
other contributions to this task) only tells how the binary was
compiled/assembled/linked, not necessarily the nature of the underlying system.
<langsyntaxhighlight PicoLisplang="picolisp">(in (cmd) # Inspect ELF header
(rd 4) # Skip "7F" and 'E', 'L' and 'F'
(prinl
Line 894 ⟶ 1,127:
(1 "Little endian")
(2 "Big endian")
(T "Bad EI_DATA") ) ) )</langsyntaxhighlight>
{{out}}
<pre>64 bits
Line 900 ⟶ 1,133:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
details: procedure options (main); /* 6 July 2012 */
declare x float, i fixed binary initial (1);
Line 912 ⟶ 1,145:
end details;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 920 ⟶ 1,153:
 
=={{header|PowerShell}}==
<langsyntaxhighlight lang="powershell">Write-Host Word Size: ((Get-WMIObject Win32_Processor).DataWidth)
Write-Host -NoNewLine "Endianness: "
if ([BitConverter]::IsLittleEndian) {
Line 926 ⟶ 1,159:
} else {
Write-Host Big-Endian
}</langsyntaxhighlight>
Note that endianness is essentially a moot point with PowerShell,
as there is only a Windows implementation currently
Line 933 ⟶ 1,166:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Enumeration
#LittleEndian
#BigEndian
Line 956 ⟶ 1,189:
PrintN("and you use Big Endian.")
EndSelect
EndIf</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">>>> import platform, sys, socket
>>> platform.architecture()
('64bit', 'ELF')
Line 972 ⟶ 1,205:
>>> socket.gethostname()
'yourhostname'
>>></langsyntaxhighlight>
 
=={{header|R}}==
Word size
<langsyntaxhighlight Rlang="r">8 * .Machine$sizeof.long # e.g. 32</langsyntaxhighlight>
Endianness
<langsyntaxhighlight Rlang="r">.Platform$endian # e.g. "little"</langsyntaxhighlight>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket/base
 
(printf "Word size: ~a\n" (system-type 'word))
(printf "Endianness: ~a\n" (if (system-big-endian?) 'big 'little))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
Endian detection translated from C. {{works with|Rakudo|2018.03}}
<syntaxhighlight lang="raku" line>use NativeCall;
say $*VM.config<ptr_size>;
my $bytes = nativecast(CArray[uint8], CArray[uint16].new(1));
say $bytes[0] ?? "little-endian" !! "big-endian";</syntaxhighlight>
{{out}}
<pre>8
little-endian</pre>
Note: Rakudo 2018.12 is introducing the endian-sensitive<code>read-int16</code> method,
which makes endian detection a little easier:
<syntaxhighlight lang="raku" line>say blob8.new(1,0).read-int16(0) == 1 ?? "little-endian" !! "big-endian"</syntaxhighlight>
 
In Rakudo 2019.01 the dynamic KERNEL variable was fleshed out with a bunch of accessors, among them:
<syntaxhighlight lang="raku" line>say join ', ', $*KERNEL, $*KERNEL.bits, $*KERNEL.arch, $*KERNEL.endian</syntaxhighlight>
{{out}}
<pre>linux, 64, x86_64, LittleEndian</pre>
 
=={{header|Retro}}==
Line 993 ⟶ 1,245:
Word Size
 
<langsyntaxhighlight Retrolang="retro">needs variations'
^variations'size</langsyntaxhighlight>
 
Returns the number of bits per cell. This is normally 32, though may be smaller or larger on embedded systems and under special cases.
Line 1,000 ⟶ 1,252:
Endianness
 
<langsyntaxhighlight Retrolang="retro">needs variations'
^variations'endian</langsyntaxhighlight>
 
Returns 0 for little endian, and 1 for big endian.
Line 1,011 ⟶ 1,263:
<br>However, there is a STORAGE built-in function that allows a program to look at (local) storage, and if there is an
<br>indicator stored anywhere in the virtual address space, it can be examined.
<langsyntaxhighlight lang="rexx">/*REXX program to examine which operating system that REXX is running under. */
 
parse source opSys howInvoked pathName
 
/*where opSys will indicate which operating system REXX is running under, and */
/*from that, one could make assumptions what the wordsize is, etc. */</langsyntaxhighlight>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby"># We assume that a Fixnum occupies one machine word.
# Fixnum#size returns bytes (1 byte = 8 bits).
word_size = 42.size * 8
Line 1,028 ⟶ 1,280:
bytes = [1].pack('S').unpack('C*')
byte_order = (bytes[0] == 0 ? 'big' : 'little') + ' endian'
puts "Byte order: #{byte_order}"</langsyntaxhighlight>
 
With [[MRI]], <code>ri Fixnum</code> states, "A Fixnum holds Integer values that can be represented in a native machine word (minus 1 bit)." This bases our claim that a Fixnum occupies one machine word.
Line 1,035 ⟶ 1,287:
 
=={{header|Rust}}==
<langsyntaxhighlight Rustlang="rust">#[derive(Copy, Clone, Debug)]
enum Endianness {
Big, Little,
Line 1,056 ⟶ 1,308:
println!("Word size: {} bytes", std::mem::size_of::<usize>());
println!("Endianness: {:?}", Endianness::target());
}</langsyntaxhighlight>
 
{{out}}
Line 1,063 ⟶ 1,315:
 
=={{header|Scala}}==
{{libheader|Scala}}<langsyntaxhighlight Scalalang="scala">import java.nio.ByteOrder
 
object ShowByteOrder extends App {
Line 1,069 ⟶ 1,321:
println(s"Word size: ${System.getProperty("sun.arch.data.model")}")
println(s"Endianness: ${System.getProperty("sun.cpu.endian")}")
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
{{works with|Chicken Scheme}}<langsyntaxhighlight lang="scheme">(define host-info
(begin
(display "Endianness: ")
Line 1,079 ⟶ 1,331:
(display "Word Size: ")
(display (if (fixnum? (expt 2 33)) 64 32))
(newline)))</langsyntaxhighlight>
{{out}}
Endianness: little-endian
Line 1,088 ⟶ 1,340:
The example below assumes that the word size is the size of a pointer.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "cc_conf.s7i";
 
Line 1,100 ⟶ 1,352:
writeln("Big endian");
end if;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,109 ⟶ 1,361:
 
=={{header|Slate}}==
<langsyntaxhighlight lang="slate">inform: 'Endianness: ' ; Platform current endianness.
inform: 'Word Size: ' ; (Platform current bytesPerWord * 8) printString.</langsyntaxhighlight>
{{out}}
<pre>
Line 1,119 ⟶ 1,371:
=={{header|Tcl}}==
This is very straightforward in Tcl. The global array <code>tcl_platform</code> contains these values. In an interactive <code>tclsh</code>:
<langsyntaxhighlight lang="tcl">% parray tcl_platform
tcl_platform(byteOrder) = littleEndian
tcl_platform(machine) = intel
Line 1,128 ⟶ 1,380:
tcl_platform(threaded) = 1
tcl_platform(user) = glennj
tcl_platform(wordSize) = 4</langsyntaxhighlight>
 
=={{header|TI-89 BASIC}}==
 
<langsyntaxhighlight lang="ti89b">Disp "32-bit big-endian"</langsyntaxhighlight>
 
=={{header|TXR}}==
Line 1,162 ⟶ 1,414:
 
No match, so big endian.
 
=={{header|UNIX Shell}}==
The getconf command gets the word size, the piped command list gets the endianness , 1 means Little and 0 means Big :
<syntaxhighlight lang="bash">
Aamrun$ getconf WORD_BIT
32
Aamrun$ echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}'
1
Aamrun$
</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|C}}
As this information cannot be reliably obtained via Wren CLI, we instead embed a Wren script in a C application and ask the host program to get it for us.
<syntaxhighlight lang="wren">/* Host_introspection.wren */
 
class C {
foreign static wordSize
foreign static endianness
}
 
System.print("word size = %(C.wordSize) bits")
System.print("endianness = %(C.endianness)")</syntaxhighlight>
<br>
We now embed this Wren script in the following C program, compile and run it.
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "wren.h"
 
void C_wordSize(WrenVM* vm) {
/* size_t typically is exactly one word */
int ws = (int)(CHAR_BIT * sizeof(size_t));
 
/* return result to Wren */
wrenSetSlotDouble(vm, 0, (double)ws);
}
 
void C_endianness(WrenVM* vm) {
/* Check if the least significant bit is located in the lowest-address byte. */
int one = 1;
char *e = (*(char *)&one) ? "little" : "big";
 
/* return result to Wren */
wrenSetSlotString(vm, 0, e);
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "wordSize") == 0) {
return C_wordSize;
} else if (isStatic && strcmp(signature, "endianness") == 0) {
return C_endianness;
}
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main() {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Host_introspection.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{out}}
The results, as expected, for my x64 Ubuntu 20.04 system are:
<pre>
word size = 64 bits
endianness = little
</pre>
 
=={{header|XPL0}}==
Line 1,169 ⟶ 1,549:
endian.
 
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
int A, B;
char C;
Line 1,178 ⟶ 1,558:
Text(0, " endian
");
]</langsyntaxhighlight>
 
{{out}}
Line 1,185 ⟶ 1,565:
Little endian
</pre>
 
=={{header|Z80 Assembly}}==
The Z80's word size is 16-bit, and you'd know this ahead of time simply because there aren't any commands that work with values any larger than that. It's also little-endian, but this can be proven without knowing it in advance using a simple store and load test.
<syntaxhighlight lang="z80">EndianTest:
ld hl,&8000
ld (&C000),hl ;store &8000 into memory.
ld a,(&C000) ;loads the byte at &C000 into A. If the Z80 were big-endian, A would equal &80. But it equals zero.
or a ;still, we need to pretend we don't already know the result and compare A to zero.
jr z,LittleEndian ;handle the case where Z80 is little-endian (which it is, so this branch is always taken.)
 
;else, do whatever you would do to show that the Z80 is big-endian (it isn't, so execution never reaches here.)</syntaxhighlight>
9,476

edits