【发布时间】:2017-12-21 00:00:33
【问题描述】:
我写了一些macros 来获取用户的输入,我需要将输入保存在某个寄存器中。 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
【问题讨论】:
-
您的代码只允许单个数字。这也将是 1 个字节,但您加载 4 个。您可以在
bl中找到您的6。 -
只是意见......你为什么要引入这些宏?他们会将您的源代码变成调试/审查的噩梦,这通常是汇编开发时间的 60-90%。如果您的目的是节省打字时间,那就忘了吧,这只是总开发时间的一小部分,阅读源代码并理解它是您可以节省最多时间的地方。宏很难阅读,尤其是参数化或嵌套的,因为您要么必须记住其中的所有指令,要么在源代码中向上/向下重新阅读它们。通常简单的
call procedure就足以节省您的打字时间。 -
@Jester 你是对的,我没注意到。
-
@Ped7g 实际上,原始项目比上面编写的代码要大。宏帮助我一次专注于一项任务。
-
IMO 在以后的调试过程中你真的会后悔这种宏,它们会使代码膨胀得很快……尤其是“get_input”是可以以几乎相同的方式使用过程的典型情况(只需在
get_input之前添加call,您就有几乎相同的代码,但在调试器的反汇编中没有膨胀,您会看到类似的call <get_input_address>代码,而不是20 条不在源代码中直接编写的新指令)。
标签: linux assembly nasm system-calls