VOGONS

Common searches


First post, by xjas

User metadata
Rank l33t
Rank
l33t

As the title says... I was talking about this with a friend recently but neither of us could come up with a definitive answer. She thought you could still do it, but it'd be pointless as you'd essentially be writing the program the same way as you would in a high-level language. Obviously the days of writing directly to the VGA registers or poking things into specific places in memory are long gone, so you need to interact with the OS to do everything.

I could see assembling stuff that runs in the Linux / OS/X console using STDIN/OUT but I can't imagine trying to e.g. use the Cocoa API or PulseAudio or an OpenGL surface in assembly without writing it inline in a C(++/#) program linking it against the C libraries anyway.

I'm not really a low-level coder so feel free to correct the hell out of what I just said. 😵

twitch.tv/oldskooljay - playing the obscure, forgotten & weird - most Tuesdays & Thursdays @ 6:30 PM PDT. Bonus streams elsewhen!

Reply 1 of 18, by Jorpho

User metadata
Rank l33t++
Rank
l33t++

https://www.grc.com/wizmo/wizmo.htm is a Windows program written in pure assembly that can use DirectX 1.0 (and later). Or so the developer claims.

See also https://www.grc.com/smgassembly.htm .

Reply 2 of 18, by Jo22

User metadata
Rank l33t++
Rank
l33t++

I can't provide you with a definitve answer to this either, sorry! 🙁
I believe assembly isn't dead, though. It's still in wide use as inline code in larger applications on recent OSes.

The reverse is also true - Microcontrollers (esp. lower end types, like PIC, ATTiny) and embedded-systems
do run programs which are mainly written in assembly, but do include some pieces of hi-level code here and there to
handle complex stuff.

For Windows, DOS and *nix there's flat assembler. That's an open source macro assembler.
- And it produces damn small applications! The Hello world program takes up about 2KB.

https://flatassembler.net/

; example of simplified Win32 programming using complex macro features

include 'win32ax.inc'

.code

start:
invoke MessageBox,HWND_DESKTOP,"Hi! I'm the example program!","Win32 Assembly",MB_OK
invoke ExitProcess,0

.end start

Attachments

  • hello.png
    Filename
    hello.png
    File size
    7.63 KiB
    Views
    822 views
    File license
    Fair use/fair dealing exception
  • fasmw.png
    Filename
    fasmw.png
    File size
    33.75 KiB
    Views
    822 views
    File license
    Fair use/fair dealing exception

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 3 of 18, by TheMobRules

User metadata
Rank Oldbie
Rank
Oldbie

Yes, you can. Although on any OS with at least minimal security your program still needs to use system calls for executing privileged instructions in kernel space. This means that the executable file will not be a plain binary like a DOS .COM file but instead will have a header, relocation metadata and all that.

Nowadays assembly is only used for specific optimizations I believe.

Reply 4 of 18, by clueless1

User metadata
Rank l33t
Rank
l33t

Following up on Jorpho's post, I listen to the Security Now! podcast (the same guy who wrote wizmo at grc.com) and this guy does most of his coding in assembly. I'm not a coder, so I'm just repeating what I hear him talking about in his podcasts.

He also wrote a nice DNS benchmark in pure assembly:
https://www.grc.com/dns/benchmark.htm

Same guy wrote SpinRite and is working on a new web auth protocol called SQRL:
https://www.grc.com/sqrl/sqrl.htm

As far as I know, he does almost all of his coding in assembly. Granted, his programs all look pretty small, but I guess one of the advantages of assembly is you can accomplish a lot with comparatively few lines...?

The more I learn, the more I realize how much I don't know.
OPL3 FM vs. Roland MT-32 vs. General MIDI DOS Game Comparison
Let's benchmark our systems with cache disabled
DOS PCI Graphics Card Benchmarks

Reply 6 of 18, by clueless1

User metadata
Rank l33t
Rank
l33t
mrau wrote:

assembly requires tons of lines of code, the resulting binary however might be quite small

That makes sense. The DNS benchmark I linked above is only 163 KB.

The more I learn, the more I realize how much I don't know.
OPL3 FM vs. Roland MT-32 vs. General MIDI DOS Game Comparison
Let's benchmark our systems with cache disabled
DOS PCI Graphics Card Benchmarks

Reply 7 of 18, by mrau

User metadata
Rank Oldbie
Rank
Oldbie

i must say thats actually unexpectedly huge... i had trouble making more than 10kb in one program when i was learning asm, it just took ages to type all that. i guess someones a geek here or there is something in there linked statically;

Reply 8 of 18, by clueless1

User metadata
Rank l33t
Rank
l33t
mrau wrote:

i must say thats actually unexpectedly huge... i had trouble making more than 10kb in one program when i was learning asm, it just took ages to type all that. i guess someones a geek here or there is something in there linked statically;

Download and run the program. It's pretty useful anyhow. It will tell you the fastest DNS servers local to you. It seems like there's a lot of functionality, and even some "eye candy" (the animation during the run). Afterward, tell me if it still seems huge for what it does.

The more I learn, the more I realize how much I don't know.
OPL3 FM vs. Roland MT-32 vs. General MIDI DOS Game Comparison
Let's benchmark our systems with cache disabled
DOS PCI Graphics Card Benchmarks

Reply 9 of 18, by spiroyster

User metadata
Rank Oldbie
Rank
Oldbie
xjas wrote:

but it'd be pointless as you'd essentially be writing the program the same way as you would in a high-level language.

I'm confused by this statement? Quite the opposite o.0 if I'm reading that right...

But yes you can. All a native x86 compiler does is translate/convert your higher-level syntax into x86 byte code (in a very intelligent way, applying optimisations and organising in a way that the higher level language allowed you to assume when you wrote it). It's fine for assembly to call higher level libraries (through C interfaces), you just need to have a better understanding of stuff like calling conventions, opcodes, registers and not get so offended by magic values plastered all over the place 😀.

This abstraction is what allows source code to be cross platform, essentially anything that runs on your x86 box.... could potentially be written in x86 assembly 😉.

Assembly is pretty much as raw as it gets, as a result you can get fastest possible performance, but it requires a lot of syntax and it needs to be solid!

Given the complexity of assembly language over higher-level ones coupled with performance gains. It's only really advantageous to use assembly in critical areas which suffer speed/efficiency problems. One notable area is SIMD, which is very platform (CPU) dependant, and is not directly exposed by most (if any) languages. To use it you need to communicate directly with the CPU, in a non higher-level way, which is where assembly comes in. In assembly you can directly copy the contents of your data into the specific SSE registers/instructions that allow SIMD. Compiler may not know to do this for you (it needs to understand that the data and operations you want to work on is SIMD compatible), so when it creates code, would be using the standard x86 registers/instructions.

Also note. Assembly is a language itself, it still needs to go through an 'compiler' (called an assembler [EDIT:] Ignore use of phrase compiler here, its an assembler 😊 ) to produce the byte code. Java and llvm do not produce x86, they produce byte-code, which run on 'virtual machines'.

Nehe has OpenGL tutorials, and quite a few of the earlier lessons have code examples in asm/masm.
OpenGL spinny cubey thing, with texturing and alpha blending written in assembly:
http://nehe.gamedev.net/data/lessons/masm/lesson08.zip

Last edited by spiroyster on 2017-04-27, 09:41. Edited 1 time in total.

Reply 10 of 18, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

Modern compilers have this kind of flow:
Source language -> Intermediate representation (abstract machine language) -> Native machine language (ASM can be output here as well)

Both GCC and LLVM operate with this type of high level structure, although LLVM holds to it much more rigidly. LLVM doesn't always use a VM (see Clang), but it's modularity allows it to be much more flexible and usable for interpreted languages, diagnostics, translators, and other things. It's less a development tool than a development toolkit.

All hail the Great Capacitor Brand Finder

Reply 11 of 18, by ynari

User metadata
Rank Member
Rank
Member

Compilers are not the same as assemblers. Assembly language is turned directly into machine code with no room for interpretation. There may be macros that necessitate multiple passes to resolve everything, but there's a direct mapping between the assembly language and machine code.

Higher level language compilers feature optimisation, so the machine or byte code generated is not entirely predictable, and the generated machine code will vary based on the compiler, even for the same processor architecture. On rare occasions compilers are incorrect, and the generated machine code does not match the original instructions.

Reply 12 of 18, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++

I agree, I just wanted to correct your comment on LLVM which wasn't nuanced enough. The note on ASM output was to provide some comparison of where an assembler would fit in the pipeline i.e. how close to raw machine code you actually operate.

Last edited by gdjacobs on 2017-04-27, 10:00. Edited 1 time in total.

All hail the Great Capacitor Brand Finder

Reply 13 of 18, by spiroyster

User metadata
Rank Oldbie
Rank
Oldbie
gdjacobs wrote:

Modern compilers have this kind of flow:
Source language -> Intermediate representation (abstract machine language) -> Native machine language (ASM can be output here as well)

Both GCC and LLVM operate with this type of high level structure, although LLVM holds to it much more rigidly. LLVM doesn't always use a VM (see Clang), but it's modularity allows it to be much more flexible and usable for interpreted languages, diagnostics, translators, and other things. It's less a development tool than a development toolkit.

True, it was my understanding that Clang is a frontend, not a backend though, used mainly for parsing C style syntax which gets compiled as LLVM byte code (or LLVM IR as you correctly say), but yes not depedant on a 'virtual machine' for execution as much as java is, or in the same way.

ynari wrote:

Compilers are not the same as assemblers. Assembly language is turned directly into machine code with no room for interpretation. There may be macros that necessitate multiple passes to resolve everything, but there's a direct mapping between the assembly language and machine code.

Higher level language compilers feature optimisation, so the machine or byte code generated is not entirely predictable, and the generated machine code will vary based on the compiler, even for the same processor architecture. On rare occasions compilers are incorrect, and the generated machine code does not match the original instructions.

Yes, have fixed the confusion. 😊

Reply 14 of 18, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++
spiroyster wrote:
gdjacobs wrote:

Modern compilers have this kind of flow:
Source language -> Intermediate representation (abstract machine language) -> Native machine language (ASM can be output here as well)

Both GCC and LLVM operate with this type of high level structure, although LLVM holds to it much more rigidly. LLVM doesn't always use a VM (see Clang), but it's modularity allows it to be much more flexible and usable for interpreted languages, diagnostics, translators, and other things. It's less a development tool than a development toolkit.

True, it was my understanding that Clang is a frontend, not a backend though, used mainly for parsing C style syntax which gets compiled as LLVM byte code (or LLVM IR as you correctly say), but yes not depedant on a 'virtual machine' for execution as much as java is, or in the same way.

I think it's more accurate that Clang uses it's own frontend as well as several of the LLVM intermediate and backend modules to build a compiler pipeline as above. The LLVM IR is used as the mid layer abstraction, but it's not interpreted nor JIT compiled in this particular case.

All hail the Great Capacitor Brand Finder

Reply 15 of 18, by spiroyster

User metadata
Rank Oldbie
Rank
Oldbie
gdjacobs wrote:

I agree, I just wanted to correct your comment on LLVM which wasn't nuanced enough. The note on ASM output was to provide some comparison of where an assembler would fit in the pipeline i.e. how close to raw machine code you actually operate.

Were you talking to me with this reply, or ynari? Don't think ynari mentioned anything about LLVM? Me only, and yes agree.

gdjacobs wrote:
spiroyster wrote:
gdjacobs wrote:

Modern compilers have this kind of flow:
Source language -> Intermediate representation (abstract machine language) -> Native machine language (ASM can be output here as well)

Both GCC and LLVM operate with this type of high level structure, although LLVM holds to it much more rigidly. LLVM doesn't always use a VM (see Clang), but it's modularity allows it to be much more flexible and usable for interpreted languages, diagnostics, translators, and other things. It's less a development tool than a development toolkit.

True, it was my understanding that Clang is a frontend, not a backend though, used mainly for parsing C style syntax which gets compiled as LLVM byte code (or LLVM IR as you correctly say), but yes not depedant on a 'virtual machine' for execution as much as java is, or in the same way.

I think it's more accurate that Clang uses it's own frontend as well as several of the LLVM intermediate and backend modules to build a compiler pipeline as above. The LLVM IR is used as the mid layer abstraction, but it's not interpreted nor JIT compiled in this particular case.

I don't know enough about Clang as I don't use it. But I think it is primarily a front-end, no back-end (which is entirely LLVM). Its static analysis tools may work on LLVM IR or more native, idk though. I'm happy to be enlightended with details about this.
https://en.wikipedia.org/wiki/Clang

Reply 16 of 18, by gdjacobs

User metadata
Rank l33t++
Rank
l33t++
spiroyster wrote:
gdjacobs wrote:

I agree, I just wanted to correct your comment on LLVM which wasn't nuanced enough. The note on ASM output was to provide some comparison of where an assembler would fit in the pipeline i.e. how close to raw machine code you actually operate.

Were you talking to me with this reply, or ynari? Don't think ynari mentioned anything about LLVM? Me only, and yes agree.

It was a reply to Ynari.

spiroyster wrote:
gdjacobs wrote:

I think it's more accurate that Clang uses it's own frontend as well as several of the LLVM intermediate and backend modules to build a compiler pipeline as above. The LLVM IR is used as the mid layer abstraction, but it's not interpreted nor JIT compiled in this particular case.

I don't know enough about Clang as I don't use it. But I think it is primarily a front-end, no back-end (which is entirely LLVM). Its static analysis tools may work on LLVM IR or more native, idk though. I'm happy to be enlightended with details about this.
https://en.wikipedia.org/wiki/Clang

Yes, the front end is where most of the unique code is, but Clang is a single binary at the end of the day, not a bunch of loosely coupled utilities. The Clang developers have selected and tested the full pipeline, not just the front end.

All hail the Great Capacitor Brand Finder

Reply 17 of 18, by Azarien

User metadata
Rank Oldbie
Rank
Oldbie
xjas wrote:

Can you still write general purpose assembly programs on modern OSes?

No problem for 32-bit Windows programs.

It is a bit of a problem if you want to write a 64-bit asm program for Windows.
Technically it's possible. But the calling convention is complicated, and the stack unwinding tables are even more complicated. You can get away without those tables, if you don't care about exception handling and debugging (meaning your program will not behave correctly under debugger).

I think there are some macros for YASM to automate some of this work, I haven't tried it.

Reply 18 of 18, by Falcosoft

User metadata
Rank Oldbie
Rank
Oldbie

Technically it's possible. But the calling convention is complicated,...

I think it's just the opposite. Compared to x86's many calling conventions (stdcall, cdecl, etc.) , there's only one (similar to x86's fastcall/register, but 4 different registers are used).
The biggest difference between Win32 and Win64 assembly is that for floating point you should (have to) use SSE and not x87.
Contrary to MS VC++ you can still write inline x64 assembly e.g. in FreePascal:

Example/difference:

{$IFDEF WIN64} //x64

function RoundS(X: single): integer;
asm
CVTSS2SI EAX,XMM0
end;

procedure FillDWord(var Dest; Count, Value: Dword);
asm
push rdi
mov rdi, rcx // Dest
mov eax, r8d // Value
mov ecx, edx // Count
rep stosd
pop rdi
end;

{$ELSE} //x86

function RoundS(X: single): integer;
asm
FLD DWORD PTR [X]
SUB ESP,4
FISTP DWORD PTR[ESP]
POP EAX
end;

procedure FillDWord(var Dest; Count, Value: Dword); register;
asm
push edi
mov edi, eax // Dest
mov eax, ecx // Value
mov ecx, edx //Count
rep stosd
pop edi
end;

{$ENDIF}

Website, Facebook, Youtube
Falcosoft Soundfont Midi Player + Munt VSTi + BassMidi VSTi
VST Midi Driver Midi Mapper