I was told bytes in assembly are counted by the byte of machine code. Is that true? If so what steps should be taken to correctly get bytes?
4 Answers
Machine code and assembly are different languages
If you write a program in assembly, therefore, you can submit it two different ways: you can either submit the source code you enter into the assembler (an assembly language solution), or else submit the object code or executable that you get out of the assembler (a machine code solution). The header of your post would be, e.g., "x86 assembly (gas
)" or "x86 machine code (Linux)" in the two cases.
Machine code solutions should typically come with a disassembly in order to make them easier to read, although that isn't technically speaking required.
Note that except on DOS (where the .COM file format has very little boilerplate), it's probably going to make more sense to submit a function rather than a full program due to the vast difference in boilerplate amount. In this case, you only have to submit the machine code for the function itself (including the ret
or equivalent at the end!), rather than an entire object file.
-
2\$\begingroup\$ "Machine code and assembly are different languages" They most definitely are not. Assembly is merely a set of mnemonics for machine code, designed to make it readable for humans. There is a 1-to-1 mapping between them, which is what allows them to be easily mapped forwards (assembly) and backwards (disassembly). As far as the computer is concerned, machine code and assembly are identical. In terms relevant to this site, assembly is just the ungolfed version of the machine code. \$\endgroup\$ Commented Jun 28, 2017 at 17:38
-
3\$\begingroup\$ @CodyGray Regardless of their similarities, I can't run a
.asm
file as an executable and expect it to work. \$\endgroup\$ Commented Aug 10, 2017 at 1:03 -
\$\begingroup\$ You cannot run machine code as an executable and expect it to work, either, @Challenger5. It has to be packaged into a binary format that is acceptable to the operating environment. \$\endgroup\$ Commented Aug 10, 2017 at 9:58
-
\$\begingroup\$ @CodyGray Well I don't know anything, so I'm just going to quietly back out of this conversation now... \$\endgroup\$ Commented Aug 10, 2017 at 18:06
-
\$\begingroup\$ It's that asm can always use
db "<machine code here>"
which is usually shorter \$\endgroup\$– l4m2Commented Jan 10, 2023 at 12:15 -
\$\begingroup\$ @CodyGray That 1:1 mapping is not entirely true even if you rule out macros, loops and other suff any but the most simplistic assemblers offer the programmer. There are assembly instruction sets where some mnemonic + operand combinations end up being the same byte representation. Like „no operation“ and OR with an immediate 0 operand both map to the same byte sequence. There are even assemblers that warn the user that the generated code from the shareware version and the paid version can be distinguished by the way how the instructions are encoded if there are several equivalent possibilities. \$\endgroup\$ Commented Nov 27 at 15:25
Assembly languages are scored by the compiled/assembled size
For example, take this x86 program to reverse the bit order of a number:
xor eax, eax
inc eax
myloop:
shr ecx, 1
adc eax, eax
jnc short myloop
This compiles into:
33 C0 40 D1 E9 13 C0 73 FA
(a series of hex bytes)
Thus, this is 9 bytes.
Another example, in a different assembly dialect:
# reverse bits of a 32 bit word
.text
.globl rbit
.type rbit,@function
rbit:
push $32 # prepare loop counter
pop %ecx
0: shrl 4(%esp) # shift lsb of argument into carry flag
adc %eax,%eax # shift carry flag into lsb
loop 0b # decrement %ecx and jump until ecx = 0
ret # return
This compiles/assembles to these 12 hex bytes:
6a 20 59 d1 6c 24 04 11 c0 e2 f8 c3
So to get your score, simply compile/assemble the assembly and get the size of the resulting file.
On Mac, this can be done as follows: (different flags may be needed for different assembly dialects)
If test.asm
is the file containing the assembly (not compiled/assembled though), then run this:
nasm -f elf test.asm
This makes an object file. Next, run either:
ld test.o -o test
or:
gcc test.o -o test
Then you can run test
as ./test
. Which of ld
and gcc
depends on the format of the assembly. If it has a main
function, use gcc
. If it has a defined start point, use ld
.
-
8\$\begingroup\$ We don't count C programs by their compiled byte size. Why should assembly be different? If you want to count it by assembled byte size, call it machine code. \$\endgroup\$– user45941Commented May 12, 2017 at 1:24
-
\$\begingroup\$ It is more important the length of code, or the number of assembly instructions that code generate? \$\endgroup\$– user58988Commented May 12, 2017 at 15:01
No. The correct way to count bytes is to count the length of the source file.
xor eax, eax
is 12 bytes. Assembly is no different to any other source-based language in this regard.
-
5\$\begingroup\$ Exactly. If the submission is scored by the byte size of the machine code, then it's a machine code submission, not an assembly submission. \$\endgroup\$– user45941Commented May 12, 2017 at 1:24
Whatever is shorter.
What about all other compiled languages? Should C/C++ be scored by binary output size? Java/Kotlin/other JVM languages by bytecode size?
Languages are defined by their interpreter, compiling should be considered a middle step.
-
\$\begingroup\$ Your link says "interpreter/compiler". "The language is defined by its implementation" is how I have always heard it. \$\endgroup\$– StephenCommented May 12, 2017 at 1:59
-
5\$\begingroup\$ I don't understand this answer. The rhetorical questions seem to be going in the opposite direction to the header. \$\endgroup\$ Commented May 12, 2017 at 9:45