汇编-如何输入中断并将其保存在寄存器中
Assembly- How to input interrupt and save it in register
我已经写了一些 macro
s 来获取用户的输入,我需要将输入保存在某个寄存器中。
gdb
显示存储值与输入值不同!这是我的代码:
%macro exit 0
mov eax, 1
int 0x80
%endmacro
%macro get_input 0 ; input is a number
push_all_general_purpose_regs
push_all_general_purpose_regs
mov eax, 3 ; system call number --> sys_read
mov ebx, 2 ; file descriptor
mov ecx, num
mov edx, 4
int 0x80
sub dword [num], '0' ; convert character to number : forexample '3'->3
POP_all_general_purpose_regs
%endmacro
%macro push_all_general_purpose_regs 0
push eax
push ebx
push ecx
push edx
%endmacro
%macro POP_all_general_purpose_regs 0
POP edx
POP ecx
POP ebx
POP eax
%endmacro
section .bss
num resb 4 ; num is where input will be stored at
section .text
global _start
_start:
get_input
lea ecx, [num] ; now ecx holds the address of input
mov ebx, [ecx] ; I want to move input to ebx
finished:
exit
这里是gdb
的输出:
(gdb) break finished
Breakpoint 1 at 0x80480ad
(gdb) run
Starting program: /assembly-project/main_project/test_project /sta/a.out
67
Breakpoint 1, 0x080480ad in finished ()
(gdb) info registers
eax 0x0 0
ecx 0x80490b4 134516916
edx 0x0 0
ebx 0xa3706 669446
esp 0xffffd390 0xffffd390
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x80480ad 0x80480ad <finished>
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb)
如图所示,我的输入是 67
但 ebx
的值是 669446
669446
= 0xA3706
这就是你输入的三个字符,让我给你看。
您的原始输入被读取为三个字节 36 37 0A
(三个字符 '6', '7', '\n'
)。
.bss
中的第 4 个字节为零,因为 .bss
部分在二进制加载+初始化期间被 linux OS 归零。
即地址 num
处的内存包含 dword
值等于 0x000A3736
.
然后你用 sub dword [num], '0'
减去 0x00000030
,所以结果是值 0x000A3706
... 那就是十进制的 669446
,正是你得到的.
所以一切正常,就像你写的那样。
要使用 sys_read
服务输入多位十进制整数,您必须在循环中逐个字符地解析它们,例如:
result = 0
for (digit : input_string) { // from first to last input character
if (!is_valid_digit(digit)) break; // will catch '\n', or other invalid char
result *= 10;
result += digit - '0';
}
// here "result" is binary integer value equal to the decimal encoded in string.
我已经写了一些 macro
s 来获取用户的输入,我需要将输入保存在某个寄存器中。
gdb
显示存储值与输入值不同!这是我的代码:
%macro exit 0
mov eax, 1
int 0x80
%endmacro
%macro get_input 0 ; input is a number
push_all_general_purpose_regs
push_all_general_purpose_regs
mov eax, 3 ; system call number --> sys_read
mov ebx, 2 ; file descriptor
mov ecx, num
mov edx, 4
int 0x80
sub dword [num], '0' ; convert character to number : forexample '3'->3
POP_all_general_purpose_regs
%endmacro
%macro push_all_general_purpose_regs 0
push eax
push ebx
push ecx
push edx
%endmacro
%macro POP_all_general_purpose_regs 0
POP edx
POP ecx
POP ebx
POP eax
%endmacro
section .bss
num resb 4 ; num is where input will be stored at
section .text
global _start
_start:
get_input
lea ecx, [num] ; now ecx holds the address of input
mov ebx, [ecx] ; I want to move input to ebx
finished:
exit
这里是gdb
的输出:
(gdb) break finished
Breakpoint 1 at 0x80480ad
(gdb) run
Starting program: /assembly-project/main_project/test_project /sta/a.out
67
Breakpoint 1, 0x080480ad in finished ()
(gdb) info registers
eax 0x0 0
ecx 0x80490b4 134516916
edx 0x0 0
ebx 0xa3706 669446
esp 0xffffd390 0xffffd390
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x80480ad 0x80480ad <finished>
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb)
如图所示,我的输入是 67
但 ebx
的值是 669446
669446
= 0xA3706
这就是你输入的三个字符,让我给你看。
您的原始输入被读取为三个字节 36 37 0A
(三个字符 '6', '7', '\n'
)。
.bss
中的第 4 个字节为零,因为 .bss
部分在二进制加载+初始化期间被 linux OS 归零。
即地址 num
处的内存包含 dword
值等于 0x000A3736
.
然后你用 sub dword [num], '0'
减去 0x00000030
,所以结果是值 0x000A3706
... 那就是十进制的 669446
,正是你得到的.
所以一切正常,就像你写的那样。
要使用 sys_read
服务输入多位十进制整数,您必须在循环中逐个字符地解析它们,例如:
result = 0
for (digit : input_string) { // from first to last input character
if (!is_valid_digit(digit)) break; // will catch '\n', or other invalid char
result *= 10;
result += digit - '0';
}
// here "result" is binary integer value equal to the decimal encoded in string.