You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 17.10下使用FASM制作可移植可执行文件的技术咨询

Hey there! Let's get you set up with FASM on Ubuntu 17.10, since you're coming from the Windows PE world. First, a quick clarification: Linux doesn't natively run PE files—it uses ELF (Executable and Linkable Format) as its standard executable format. FASM on Linux defaults to generating ELF files, which is what you'll want for running programs directly on your Ubuntu system.

Below, I'll walk you through creating a program that replicates your print_eax functionality, plus add a read_eax equivalent for reading hex input into EAX, using Linux system calls (since we don't have win32a.inc or your custom MyLib.inc here).

1. Full Example Code

Save this as eax_utils.asm:

format ELF executable 32
entry start

section '.text' executable
start:
    ; Example 1: Print a hardcoded EAX value (0xFFFF)
    mov eax, 0xFFFF
    call print_eax_hex

    ; Example 2: Read hex input from user, then print it
    ; call read_eax_hex
    ; call print_eax_hex

    ; Exit the program cleanly
    mov eax, 1          ; System call number for sys_exit
    xor ebx, ebx        ; Return code 0 (success)
    int 0x80            ; Trigger Linux system call

;----------------------------------------------------------------------
; print_eax_hex: Prints the value in EAX as an 8-digit hex string
;----------------------------------------------------------------------
print_eax_hex:
    pushad                   ; Save all registers to stack
    mov ecx, 8               ; 32-bit value = 8 hex digits
    mov edi, hex_buffer      ; Point to our output buffer

next_digit:
    rol eax, 4               ; Rotate EAX left to get the next 4 bits
    mov edx, eax
    and edx, 0x0f            ; Isolate the lowest 4 bits
    mov dl, [hex_chars + edx]; Convert to ASCII character
    mov [edi], dl            ; Store character in buffer
    inc edi
    dec ecx
    jnz next_digit           ; Repeat until all 8 digits are processed

    ; Print the hex string
    mov eax, 4          ; System call number for sys_write
    mov ebx, 1          ; File descriptor: stdout (1)
    mov ecx, hex_buffer ; Pointer to our hex string
    mov edx, 8          ; Length of the string
    int 0x80

    ; Print a newline for readability
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    popad                    ; Restore original register values
    ret

;----------------------------------------------------------------------
; read_eax_hex: Reads a hex string from stdin and stores it in EAX
; Handles 0-9, A-F, a-f; ignores newlines
;----------------------------------------------------------------------
read_eax_hex:
    pushad
    ; Read input from stdin into our buffer
    mov eax, 3          ; System call number for sys_read
    mov ebx, 0          ; File descriptor: stdin (0)
    mov ecx, input_buffer
    mov edx, 10         ; Max characters to read (includes newline)
    int 0x80

    ; Convert the input string to a 32-bit hex value in EAX
    xor eax, eax
    mov ecx, input_buffer

convert_loop:
    mov dl, [ecx]
    test dl, dl
    jz convert_done     ; Exit if we hit a null terminator
    cmp dl, 0xA
    je convert_done     ; Exit if we hit a newline
    ; Validate character is a valid hex digit
    cmp dl, '0'
    jb invalid_input
    cmp dl, '9'
    jbe process_digit
    cmp dl, 'A'
    jb invalid_input
    cmp dl, 'F'
    jbe process_upper
    cmp dl, 'a'
    jb invalid_input
    cmp dl, 'f'
    jbe process_lower

invalid_input:
    xor eax, eax        ; Set EAX to 0 if input is invalid
    jmp convert_done

process_digit:
    sub dl, '0'
    jmp shift_and_add

process_upper:
    sub dl, 'A' - 10    ; Convert 'A'-'F' to 10-15
    jmp shift_and_add

process_lower:
    sub dl, 'a' - 10    ; Convert 'a'-'f' to 10-15

shift_and_add:
    shl eax, 4          ; Shift current value left by 4 bits (multiply by 16)
    add al, dl          ; Add the new digit
    inc ecx
    jmp convert_loop

convert_done:
    mov [saved_eax], eax; Save result (popad will overwrite EAX)
    popad
    mov eax, [saved_eax]; Restore the converted value to EAX
    ret

section '.data' writeable
hex_chars     db '0123456789ABCDEF'  ; Hex digit lookup table
hex_buffer    db 8 dup(0)            ; Buffer for printed hex string
newline       db 0xA                 ; Newline character
input_buffer  db 10 dup(0)           ; Buffer for input string
saved_eax     dd 0                   ; Temporary storage for read_eax result

2. Compile and Run

Since you already installed FASM with sudo apt install fasm, follow these steps:

  • Compile the code:
    fasm eax_utils.asm
    
    This will generate an executable file named eax_utils.
  • Run the program:
    ./eax_utils
    
    You'll see 0000FFFF printed (since 0xFFFF is a 16-bit value, the 32-bit EAX fills the upper bits with 0s). To test the input functionality, uncomment the call read_eax_hex and call print_eax_hex lines in the start section, recompile, and run—you can type a hex value like 123ABC and it will print back 00123ABC.

3. Key Differences from Windows

  • No Win32 Libraries: Linux uses system calls (triggered via int 0x80 for 32-bit programs) instead of Windows API functions like ExitProcess.
  • ELF vs PE: FASM generates ELF files by default on Linux—this is the native format for Linux systems, so it's portable across compatible Linux distributions.
  • Custom Utilities: Since there's no pre-built win32a.inc equivalent, we implement the hex print/read logic manually using basic string manipulation and system calls.

If you ever need to generate a PE file (for example, to run on Windows via Wine), you can still use format PE console in FASM on Linux—but keep in mind you'll need to use Windows-compatible system calls or libraries, and the PE file won't run natively on Ubuntu.

内容的提问来源于stack exchange,提问作者Mr. Weirdo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:03:12