linux - 使用 NASM 将数字写入文件

标签 linux assembly x86 nasm

如何使用 NASM 将变量写入文件? 例如,如果我执行一些数学运算 - 如何将运算结果写入文件?

我的文件结果仍然为空。

我的代码:

%include "io.inc"
section .bss
        result db 2        
section .data
        filename db "Downloads/output.txt", 0
section .text
        global CMAIN
        CMAIN:
        mov eax,5
        add eax,17
    
        mov [result],eax
        PRINT_DEC 2,[result]
        jmp write
write:
                
        mov EAX, 8
        mov EBX, filename
        mov ECX, 0700
        int 0x80
        mov EBX, EAX
        mov EAX, 4
        mov ECX, [result]
        int 0x80
        mov EAX, 6
        int 0x80
        mov eax, 1
        int 0x80
        jmp exit  
exit:   
        xor eax, eax
        ret

最佳答案

您必须以这种方式随后实现ito(整数到ascii)len。此代码经过测试并在 Ubuntu 中正常运行。

section .bss
    answer resb 64

section .data
    filename db "./output.txt", 0

section .text
    global main

main:
    mov eax,5
    add eax,44412

    push    eax         ; Push the new calculated number onto the stack
    call    itoa


    mov EAX, 8
    mov EBX, filename
    mov ECX, 0x0700
    int 0x80

    push    answer
    call    len

    mov EBX, EAX
    mov EAX, 4
    mov ECX, answer
    movzx EDX, di ; move with extended zero edi. length of the string
    int 0x80 
    mov EAX, 6
    int 0x80 
    mov eax, 1
    int 0x80
    jmp exit
exit:   
    xor eax, eax
    ret

itoa:
    ; Recursive function. This is going to convert the integer to the character.
    push    ebp         ; Setup a new stack frame
    mov ebp, esp
    push    eax         ; Save the registers
    push    ebx
    push    ecx
    push    edx

    mov eax, [ebp + 8]      ; eax is going to contain the integer
    mov ebx, dword 10       ; This is our "stop" value as well as our value to divide with
    mov ecx, answer     ; Put a pointer to answer into ecx
    push    ebx         ; Push ebx on the field for our "stop" value

itoa_loop:
    cmp eax, ebx        ; Compare eax, and ebx
    jl  itoa_unroll     ; Jump if eax is less than ebx (which is 10)
    xor edx, edx        ; Clear edx
    div ebx         ; Divide by ebx (10)
    push    edx         ; Push the remainder onto the stack
    jmp itoa_loop       ; Jump back to the top of the loop
itoa_unroll:
    add al, 0x30        ; Add 0x30 to the bottom part of eax to make it an ASCII char
    mov [ecx], byte al      ; Move the ASCII char into the memory references by ecx
    inc ecx         ; Increment ecx
    pop eax         ; Pop the next variable from the stack
    cmp eax, ebx        ; Compare if eax is ebx
    jne itoa_unroll     ; If they are not equal, we jump back to the unroll loop
                ; else we are done, and we execute the next few commands
    mov [ecx], byte 0xa     ; Add a newline character to the end of the character array
    inc ecx         ; Increment ecx
    mov [ecx], byte 0       ; Add a null byte to ecx, so that when we pass it to our
                    ; len function it will properly give us a length

    pop edx         ; Restore registers
    pop ecx
    pop ebx
    pop eax
    mov esp, ebp
    pop ebp
    ret


len:
    ; Returns the length of a string. The string has to be null terminated. Otherwise this function
    ; will fail miserably. 
    ; Upon return. edi will contain the length of the string.

    push    ebp         ; Save the previous stack pointer. We restore it on return
    mov ebp, esp        ; We setup a new stack frame
    push    eax         ; Save registers we are going to use. edi returns the length of the string
    push    ecx

    mov ecx,  [ebp + 8]     ; Move the pointer to eax; we want an offset of one, to jump over the return address

    mov edi, 0          ; Set the counter to 0. We are going to increment this each loop

len_loop:           ; Just a quick label to jump to
    movzx   eax, byte [ecx + edi]   ; Move the character to eax.
    movsx   eax, al         ; Move al to eax. al is part of eax.
    inc di          ; Increase di.
    cmp eax, 0          ; Compare eax to 0.
    jnz     len_loop        ; If it is not zero, we jump back to len_loop and repeat.
    dec di          ; Remove one from the count

    pop ecx         ; Restore registers
    pop eax
    mov esp, ebp        ; Set esp back to what ebp used to be.
    pop ebp         ; Restore the stack frame
    ret             ; Return to caller

关于linux - 使用 NASM 将数字写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26570584/

相关文章:

python3.3在linux中找不到libpython3.3m.so(pip-3.3)

c++ - MSVC : Invalid memcpy optimization?

memory - GDB 中的 x86 标签和 LEA

linux - 在隔离的unix环境中执行终端命令

sql - 如何运行 sed 命令来接收 sed 文件并输出 sql 文件

linux - 使用 settype 而不是 setname 搜索 ipset

linux - 汇编代码一直显示段错误

c++ - 将 C++ 代码转换为 SPIM 程序集

assembly - NASM程序集将输入转换为整数?

c++ - 当我们将数据从 ax 移动到端口地址时会发生什么