显示寄存器的内容

时间:2015-12-01 22:03:09

标签: linux gcc assembly nasm

我需要帮助显示寄存器的内容。我的代码在下面。我已经能够显示数据寄存器的值但我想显示标志状态。例如1或0.如果要显示其他寄存器的内容,如esi,ebp,将会很有帮助。

我的代码没有打印标志的状态..我错过了什么

section .text
global _start       ;must be declared for using gcc
_start :                     ;tell linker entry point

mov eax,msg         ; moves message "rubi" to eax register
mov [reg],eax       ; moves message from eax to reg variable


mov edx, 8   ;message length
mov ecx, [reg];message to write
mov ebx, 1      ;file descriptor (stdout)
mov eax, 4      ;system call number (sys_write)
int 0x80        ;call kernel

mov eax, 100
mov ebx, 100
cmp ebx,eax

pushf
pop dword eax

mov [save_flags],eax

mov edx, 8        ;message length
mov ecx,[save_flags]         ;message to write
mov ebx, 1          ;file descriptor (stdout)
mov eax, 4          ;system call number (sys_write)
int 0x80     


mov eax, 1      ;system call number (sys_exit)
int 0x80        ;call kernel

section .data

msg db "rubi",10

section .bss

reg resb 100

save_flags resw 100

2 个答案:

答案 0 :(得分:3)

我在这里没有任何想象,因为这似乎是一项家庭作业(今天有两个人问了同样的问题)。此代码应作为一个函数,并可以提高其性能。由于我没有在课堂上获得荣誉学位或A,因此提供最佳解决方案对我来说没有意义,但您可以从中学习:

    BITS_TO_DISPLAY equ 32       ; Number of least significant bits to display (1-32)

section .text
global _start                    ; must be declared for using gcc
_start :                         ;    tell linker entry point

    mov edx, msg_len             ; message length
    mov ecx, msg                 ; message to write
    mov ebx, 1                   ; file descriptor (stdout)
    mov eax, 4                   ; system call number (sys_write)
    int 0x80                     ; call kernel

    mov eax, 100
    mov ebx, 100
    cmp ebx,eax

    pushf
    pop dword eax

    ; Convert binary to string by shifting the right most bit off EAX into
    ; the carry flag (CF) and convert the bit into a '0' or '1' and place
    ; in the save_flags buffer in reverse order. Nul terminate the string
    ; in the event you ever wish to use printf to print it

    mov ecx, BITS_TO_DISPLAY     ; Number of bits of EAX register to display
    mov byte [save_flags+ecx], 0 ; Nul terminate binary string in case we use printf
bin2ascii:
    xor bl, bl                   ; BL = 0
    shr eax, 1                   ; Shift right most bit into carry flag
    adc bl, '0'                  ; bl = bl + '0' + Carry Flag
    mov [save_flags-1+ecx], bl   ; Place '0'/'1' into string buffer in reverse order
    dec ecx
    jnz bin2ascii                ; Loop until all bits processed

    mov edx, BITS_TO_DISPLAY     ; message length
    mov ecx, save_flags          ; address of binary string to write
    mov ebx, 1                   ; file descriptor (stdout)
    mov eax, 4                   ; system call number (sys_write)
    int 0x80

    mov eax, 1                   ;system call number (sys_exit)
    int 0x80                     ;call kernel

section .data
msg db "rubi",10
msg_len equ $ - msg

section .bss
save_flags resb BITS_TO_DISPLAY+1 ; Add one byte for nul terminator in case we use printf

这段代码背后的想法是我们不断地将 EAX 寄存器中的位(使用SHR instruction)一次移位到右边一位。从寄存器移出的位被置于进位标志(CF)中。我们可以使用ADC将进位标志(0/1)的值添加到ASCII' 0'获得' 0`和' 1'的ASCII值。我们将这些字节以相反的顺序放入目标缓冲区,因为我们通过位从右向左移动。

BITS_TO_DISPLAY可以设置在1到32之间(因为这是32位代码)。如果您对寄存器的低8位感兴趣,请将其设置为8.如果要显示32位寄存器的所有位,请指定32。

答案 1 :(得分:2)

请注意,您可以pop直接进入内存。

如果你想用write(2)二进制转储寄存器和标志数据,你的系统调用需要传递指向缓冲区的指针,而不是数据本身。使用mov-immediate将地址输入寄存器,而不是加载。或lea使用RIP相对寻址模式。或者将指针传递给它在堆栈上的位置,而不是将其复制到全局!

mov edx, 8        ;message length
mov ecx,[save_flags]         ;message to write    ;;;;;;; <<<--- problem
mov ebx, 1          ;file descriptor (stdout)
mov eax, 4          ;system call number (sys_write)
int 0x80     

将错误地址传递给write(2)不会导致您的程序收到SIGSEGV,就像您在用户空间中使用该地址一样。相反,write将返回EFAULT。并且您没有检查系统调用的返回状态,因此您的代码没有注意到。

mov eax,msg         ; moves message "rubi" to eax register
mov [reg],eax       ; moves message from eax to reg variable

mov ecx, [reg];

这太傻了。你应该mov ecx, msg将msg的地址输入ecx,而不是通过内存反弹。

您是否正在为64位构建?我看到你使用8个字节的消息长度。如果是这样,您应该使用64位函数调用ABI(syscall,而不是int 0x80)。系统呼叫号码不同。请参阅中某个链接中的表格。 32位ABI只能接受32位指针。如果您尝试传递一个设置了任何high32位的指针,则会出现问题。

您可能还希望将数字格式化为字符串,除非您想将程序的输出传输到hexdump