使用 Linux 系统调用将用 EQU 定义的值写入控制台

Writing a value defined with EQU to the console using Linux system calls

写入由某些标签指向的控制台文本我正在使用以下代码:

section .data                           ;Data segment
   userMsg db 'Please enter a number: ' ;Ask the user to enter a number
   lenUserMsg equ $-userMsg             ;The length of the message             


section .text          ;Code Segment
   global _start

_start:                
   ;User prompt
   mov eax, 4
   mov ebx, 1
   mov ecx, userMsg
   mov edx, lenUserMsg
   int 80h

   ; Exit code
   mov eax, 1
   mov ebx, 0
   int 80h

但是如果我想写入存储在 lenUserMsg 值下的控制台值怎么办?

我试过以下:

   ...
   ;User prompt
   mov eax, 4
   mov ebx, 1
   mov ecx, lenUserMsg
   mov edx, 1
   int 80h
   ...

它编译并且 运行 没有崩溃,但没有向控制台写入任何内容。

lenUserMsg 未存储。 EQU 指令使它只是一个宏,其值(字符串!)在 assemble 时间计算并替换其 "name" 的任何出现。没有机会在运行时获取它的值。如果您想要一个存储在 .data 部分中的值,您可以像定义任何其他值一样定义它 - 使用方括号。我猜你想看到 lenUserMsg 的十进制表示,因为 Int 80h/EAX=4 只打印字符串,所以我在下面的例子中添加了一个转换例程:

section .data                            ;Data segment
    userMsg db 'Please enter a number: ' ;Ask the user to enter a number
    lenUserMsg dd $-userMsg              ;The length of the message

section .bss
    buf resb 16

section .text          ;Code Segment
global _start

_start:
    ;User prompt
    mov eax, 4
    mov ebx, 1
    mov ecx, userMsg
    mov edx, [lenUserMsg]
    int 80h

    mov eax, [lenUserMsg]
    mov edi, buf
    call EAX_to_DEC

    mov edx, eax
    mov ecx, buf
    mov ebx, 1
    mov eax, 4
    int 80h

    ; Exit code
    mov eax, 1
    mov ebx, 0
    int 80h

EAX_to_DEC:                     ; ARG: EDI pointer to string buffer
    mov ebx, 10                 ; Divisor = 10
    xor ecx, ecx                ; ECX=0 (digit counter)
    .L1:                        ; First Loop: store the remainders
    xor edx, edx                ; Don't forget it!
    div ebx                     ; EDX:EAX / EBX = EAX remainder EDX
    push dx                     ; Push the digit in DL (LIFO)
    add cl, 1                   ; = inc cl (digit counter)
    or eax, eax                 ; AX == 0?
    jnz .L1                     ; No: once more (jump to the first @@ above)
    mov ebx, ecx                ; Store count of digits
    .L2:                        ; Second loop: load the remainders in reversed order
    pop ax                      ; get back pushed digits
    or al, 00110000b            ; to ASCII
    stosb                       ; Store AL to [EDI] (EDI is a pointer to a buffer)
    loop .L2                    ; until there are no digits left
    mov eax, ebx                ; Restore Count of digits
    ret                         ; RET: EAX length of string