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:
This will generate an executable file namedfasm eax_utils.asmeax_utils. - Run the program:
You'll see./eax_utils0000FFFFprinted (since 0xFFFF is a 16-bit value, the 32-bit EAX fills the upper bits with 0s). To test the input functionality, uncomment thecall read_eax_hexandcall print_eax_hexlines in thestartsection, recompile, and run—you can type a hex value like123ABCand it will print back00123ABC.
3. Key Differences from Windows
- No Win32 Libraries: Linux uses system calls (triggered via
int 0x80for 32-bit programs) instead of Windows API functions likeExitProcess. - 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.incequivalent, 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

