0

How come this (https://www.mycompiler.io/new/asm-x86_64):

section .data
    msg db "Hello world!", 0ah

section .text
    global _start

_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 13
    syscall
    mov rax, 60
    mov rdi, 0
    syscall

and this (https://www.tutorialspoint.com/compile_asm_online.php):

section .text
 global _start       ;must be declared for using gcc
_start:                     ;tell linker entry point
 mov edx, len    ;message length
 mov ecx, msg    ;message to write
 mov ebx, 1     ;file descriptor (stdout)
 mov eax, 4     ;system call number (sys_write)
 int 0x80        ;call kernel
 mov eax, 1     ;system call number (sys_exit)
 int 0x80        ;call kernel

section .data
 msg    db  'Hello, world!',0xa ;our dear string
 len    equ $ - msg         ;length of our dear string

do the exact same thing, but when I switch the codes between the two compilers, it reads both 'Instructions not supported in 32-bit mode' (1st compiler to 2nd) and 'signal: bad system call (core dumped)' (2nd compiler to 1st)

When I try to convert the 2nd compiler to 64 bits mode with 'bits 64', it reads: '64-bit unsigned relocation zero-extended from 32 bits [-w+zext-reloc] Segmentation fault (core dumped)'

Reck
  • 11
  • 4
  • It's not about the different ways, it's about the intended execution environment. The first is 64 bit code intended for a 64 bit OS, the second is 32 bit code intended for 32 bit OS (or a 64 bit running 32 bit program). – Jester May 20 '23 at 22:19
  • Question: How come that the register ax has different properties when in 64 bit mode compared to 32 bit mode? – Reck May 20 '23 at 22:29
  • It doesn't. `ax` is 16 bit in either mode (none of your code uses `ax` though). – Jester May 20 '23 at 23:00
  • But why does ax, eax and rax have different directives, but they are the *same registers – Reck May 20 '23 at 23:17
  • 2
    Not sure what your question about "different directives" means. There's `al` (8 bits wide), `ax` (16 bits wide), `eax` (32 bits wide), and `rax` (64 bits wide) where `al` is an alias for the low 8 bits of `ax`/`eax`/`rax`, while `ax` is an alias for the low 16 bits of `eax`/`rax`. The original x86 had only the 8- and 16-bit registers, while 80386 provides the 32-bit registers, and x64 provides the 64-bit registers. – Erik Eidt May 20 '23 at 23:24
  • The 32-bit code (using `int 0x80` Linux system calls) will work on most systems if assembled into a 64-bit executable (but don't: [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730)), as long as you don't try to make it a PIE ([32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427)) – Peter Cordes May 20 '23 at 23:26
  • 1
    If you use `bits 64` to put 64-bit machine code into an executable that will run with the CPU in 32-bit mode, some things will happen to work the same, but `inc rcx` will run as `dec eax` / `inc ecx` because of the `0x48` byte being a REX.W prefix in 64-bit mode, but a 1-byte `dec` instruction in other modes. ([x86 32 bit opcodes that differ in x86-x64 or entirely removed](https://stackoverflow.com/q/32868293)). Don't use a `bits` directive unless you're making an OS that switches modes. Same for [`.code32` in GAS](https://stackoverflow.com/q/36861903) – Peter Cordes May 20 '23 at 23:30
  • 1
    Also related: [Is x86 32-bit assembly code valid x86 64-bit assembly code?](https://stackoverflow.com/q/44089163) . In general asm is specific to one mode of one CPU architecture, for one OS. Like your first code will only work in 64-bit mode on x86-64 under Linux, because it uses 64-bit registers (x86-64), the x86-64 System V system-call calling convention (multiple OSes for x86-64), and Linux system-call numbers in RAX. Also, asm source is specific to the assembler. Both your sources are in NASM syntax, or could be valid FASM. But would mean something different if assembled with MASM. – Peter Cordes May 20 '23 at 23:34
  • 1
    When building an executable, we need a long chain of consistency running throughout the environment, a consistency of the intended target architecture processor and operating system.. The consistency requirement starts with the source code, goes to the assembler, compiler, linker, to the libraries, to the executable file format, and the operating system loader and system call handlers. We cannot arbitrarily interchange some piece of the chain from one environment with that of another. – Erik Eidt May 20 '23 at 23:38

0 Answers0