Since it requires a 100% rewrite of assembly language programs to port from one platform (e.g. 80x88) to another (e.g. AIX Unix), assembly language, by definition, is unportable.
Quoting myself here: "Hate to be pedantic, but actually, it *is* portable! As long as you stay on the same Arch anyway." -you can see that I was talking about portability on the same hardware.
What are the characteristics that allow a language to be portable? Packaging has a lot to do with it. If you write a Java program, it is cross-platform *only* to the extent that a Java run-time environment (VM, JIT-engine, etc.) is available on the target platform.
If we confine our discussion to x86 hardware, we have a few OSs to contend with (Windows, Linux, BSD, OS X, DOS, etc.), but we can see that we _do not_ need to alter any of our core application code when transitioning from one OS to the other. This is because it is the CPU which executes the Machine Language instructions -- not the Operating System. All that is needed is a library of wrapper functions (just like C and C++ have their libs which do the same thing) to isolate the calls to operating system services.
For example: One can write a program (as long as you restrict yourself to command-line "filter-type" programs and don't do GUI) in HLA [
http://www.artofasm.com ] using its standard library and the program will execute (without any change to the source code) on both Linux and Windows (other platforms in the future) {even on DOS with the right setup}.