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

为什么这段32位汇编代码无法正确实现文件读取与写入?

问题分析与解决

核心问题原因

  • fprintf参数传递错误:
    最初使用push dword number时,传递的是number变量的内存地址而非读取到的字节内容,%d格式符会打印该地址值,也就是你看到的“类似偏移量的数值”;改成push dword [number]后,因number仅占1字节,push操作会将该字节与后续3个字节的垃圾数据一起作为32位整数传递,导致打印随机值。
  • 格式符使用不当:
    若要原样复制文件的ASCII内容,应使用%c格式符打印字符;若需打印字节的数值,则需将1字节数据扩展为完整的32位整数后再传递。
  • fread参数顺序不规范(虽未影响当前结果):
    msvcrt的fread原型为size_t fread(void *ptr, size_t size, size_t count, FILE *stream),C调用约定要求参数从右到左入栈,正确顺序应为stream → count → size → ptr,你当前代码颠倒了size和count的顺序,虽因两者均为1未引发问题,但需修正以符合规范。

修正后的代码

bits 32 
global start        

extern exit, fread, fprintf, fopen, fclose
import exit msvcrt.dll   
import fopen msvcrt.dll  
import fclose msvcrt.dll
import fread msvcrt.dll
import fprintf msvcrt.dll
 
segment data use32 class=data
    reading_file db "trial.txt", 0
    access_mode1 db "r", 0
    printing_file db "trial2.txt", 0
    access_mode2 db "w", 0
    read_descriptor resd 1
    print_descriptor resd 1
    number resb 1
    print_format db "%c", 0  ; 用%c打印字符实现原样复制,若需打印数值可改为%d并配合后续扩展逻辑

segment code use32 class=code
    start:
        ; 打开读取文件
        push dword access_mode1
        push dword reading_file
        call [fopen] 
        add esp, 4*2
        
        cmp eax, 0
        je end_of_code
        mov [read_descriptor], eax
        
        ; 打开写入文件
        push dword access_mode2
        push dword printing_file
        call [fopen]
        add esp, 4*2
        
        cmp eax, 0
        je end_of_code
        mov [print_descriptor], eax
        
        read_loop:
            ; 修正fread参数顺序:stream → count → size → ptr
            push dword [read_descriptor]
            push dword 1                 ; count
            push dword 1                 ; size
            push dword number
            call [fread]
            add esp, 4*4
            
            cmp eax, 0
            je end_of_code
            
            ; 传递字节内容,%c仅取低字节,push dword不会影响结果
            push dword [number]          
            push dword print_format
            push dword [print_descriptor]
            call [fprintf]
            add esp, 4*3
            
        jmp read_loop
        
        end_of_code:
        ; 关闭文件
        push dword [read_descriptor]
        call [fclose]
        add esp, 4
        
        push dword [print_descriptor]
        call [fclose]
        add esp, 4
        
        push dword 0      
        call [exit]       

关于同时操作两个文件

完全可以同时操作多个文件,只要每个文件拥有独立的文件描述符即可,你代码中read_descriptor和print_descriptor的逻辑是正确的。

内容的提问来源于stack exchange,提问作者Diana R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:05:15