显示寄存器的内容

嗨,我需要帮助显示寄存器的内容。我的代码是below.i已经能够显示数据寄存器的值,但我想显示标志状态。 例如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 

因为这似乎是一项家庭作业(我今天有两个人问过同样的问题),所以我不想在这里找到任何东西。 这个代码应该作为一个函数,它可以提高性能。 由于我没有获得荣誉学位或班上的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指令 )一次一位地移位到右边的位。 从寄存器移出的位被放置在进位标志(CF)中。 我们可以使用ADC将进位标志(0/1)的值加到ASCII'0'来得到'0'和'1'的ASCII值。 我们将这些字节以相反的顺序放入目标缓冲区,因为我们是从右向左移动的。

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

请注意,您可以直接pop到内存中。

而如果你想用二进制转储寄存器和标志数据write(2) ,你的系统调用需要传递一个指针到缓冲区,而不是数据本身。 使用mov-immediate将地址存入寄存器,而不是执行加载。 或者使用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地址写入ecx,而不是通过内存弹出。


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


你可能也想要把数字格式化成一个字符串,除非你想把你的程序输出到hexdump