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

时间:2015-12-12 16:08:39

标签: assembly nasm x86-64 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
   ...

它编译并运行而不会崩溃但是没有向控制台写任何内容。

1 个答案:

答案 0 :(得分:1)

lenUserMsg未存储。 EQU指令使它只是一个宏,其值(字符串!)在汇编时计算,并替换其名称"的任何出现。没有机会在运行时获得它的价值。如果您想要一个存储在.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