Запись значения, определенного с помощью EQU, в консоль с помощью системных вызовов Linux
Для записи в консоль текста, на который указывает какая-то метка, я использую следующий код:
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 ответ:
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