NASM中的输出数据寄存器值 [英] Output Data Register value in NASM

查看:456
本文介绍了NASM中的输出数据寄存器值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新来的人,我已经有一个问题了.

new guy here, and already I have a question.

我正在改编Jeff Duntemann的汇编手册中使用的示例代码,我想将存储在数据寄存器中的整数值打印出到终端吗?

I'm adapting example code used in Jeff Duntemann's assembly books, and I want to print out an integer value stored in a data register to terminal?

以下代码的作用是:打印出正确的字符串,将ECX中的值压入,但是到达以下内容时:

What the following code below does is that it prints out the strings okay, pushes value in ECX okay, but when it gets to the following:

                pop ecx
                mov eax,4                          
                mov ebx,1                          
                mov edx, ecx

                int 80h  

它不会在终端上显示edx的内容,尽管我想我是用mov eax,4等告诉它的.

It doesn't display the contents of edx on the terminal, though I think I told it to with mov eax,4 etc.

有人能给我指针"(双关语意)吗?

Anyone able to give me any "pointers" (pun intended)?

参考代码(2012年6月17日修改):

Code for reference (amended as of 17/06/2012) :

SECTION .data
    submessage: db "I am subtracting 5 from 10!", 10
    msglen: equ $-submessage

    ansmsg: db "Answer is:", 10
    msglen2: equ $-ansmsg
    EOL: db 10

SECTION .bss
    msg: resd 2                                         ; reserve space for 2 dwords

SECTION .text

global _start

_start: nop

;Displays test on shell
                    mov eax,4                           ;print to terminal     
                    mov ebx,1                                      
                    mov ecx, submessage
                    mov edx, msglen
                    int 80h                             ;"I am subtracting 5 from 10!"

                    mov eax,4                           ;print to terminal   
                    mov ebx,1                                            
                    mov ecx, ansmsg
                    mov edx, msglen2
                    int 80h                             ;"Answer is..."

;Subtraction operation below:                  
                            mov edx, 10
                            sub edx, 5
                            mov [msg], edx                ; store 5 in msg


; now we need to print  msg to terminal                            


                            mov eax, 4                  ;print to terminal 
                            mov ebx, 1
                            mov dword [msg+1], 0xa      ;helps prints something out! 

                    ;Encountered problem here= prints out 'Answe' instead of integer '5'

                            push dword 2                ; store size of msg
                            push dword [msg]            ; push to stack contents of msg 
                            int 80h                    

                            add esp, 3                  ;clean stack (2 push calls *4)
                            int 80h

; I like labels :)

sys_exit:                            mov eax,1                   ;exit status
                                    mov ebx,0                        
                                    int 80h  
                                        nop

PS-如果我的行缩进很糟,我想知道如何改进它;一旦您克服了最初的学习驼峰",恕我直言,学习程序集就会变得更具吸引力:)

PS- If my line indenting sucks I'd like to know how I can improve it; IMHO learning assembly gets more appealing once you get over the initial learning "hump" :)

推荐答案

首先,感谢您提出这个问题-它促使我在80小时内学习,这是我以前不熟悉的.

First, thanks for the question-- it motivated me to study up in int 80h, something I wasn't familiar with before.

您的程序以当前形式做什么?它打印什么吗?如果我在脑海中正确执行了该命令,则希望它打印出第一条消息,然后崩溃.由于存在缓冲,它甚至可能不会在怀疑的崩溃之前显示第一条消息.

What does your program do in its current form? Does it print anything? If I'm executing it correctly in my head, I expect it to print the first message and then crash. Due to buffering, it might not even show the first message before the suspected crash.

int 80h/eax = 4映射到write()函数.运行"man 2 write"以获取完整的文档.函数原型为:

int 80h/eax=4 maps to the write() function. Run 'man 2 write' to get the full documentation. The function prototype is:

ssize_t write(int fd, const void *buf, size_t count);

因此,eax = 4,ebx = fd,ecx = buf,edx = count.如果您想对代码注释更讲究,则"mov eax,4"表示向文件写入字符串",而"mov ebx,1"表示指定映射到STDOUT(终端)的文件#1".

So, eax = 4, ebx = fd, ecx = buf, edx = count. If you want to be more pedantic with your code comments, "mov eax,4" means "write a string to a file" while "mov ebx,1" means "specify file #1, which maps to STDOUT (the terminal)".

我希望第一个int 80h调用能够打印出一些东西.第二个int 80h调用是可疑的.此时eax和ebx保持不变.但是,edx也是不变的,它保留了第一个字符串的字符串长度.更有问题的是您将值5放入ecx. ecx对要写入的字符串(而不是要写入的值)持有一个 pointer .因此,当您在其中放置5并调用中断时,int会尝试打印从地址0x00000005开始的字符串.几乎可以肯定会导致段错误(崩溃).

I expect the first int 80h call to print something. The second int 80h call is suspect. At this point eax and ebx are unchanged. However, edx is also unchanged and that holds the string length of the first string. More problematic is that you are putting the value 5 into ecx. ecx holds a pointer to the string to be written, not a value to be written. So when you put 5 in there and call the interrupt, the int will try to print a string starting at address 0x00000005. This is almost certain to cause a segfault (crash).

此外,如果我正确阅读了int 80h文档,则示例中的push/pop堆栈操作没有任何意义.

Also, if I'm reading the int 80h docs correctly, the push/pop stack ops in your example don't have any relevance.

将数字打印为字符串是ASM中比较繁琐的事情.您需要将数字转换为字符串,然后可以使用int 80h进行打印.如果您只想打印一位数字,可以使用以下方法作弊:

Printing a number as a string is a bit of a chore in ASM. You need to convert the number into a string and then you can print it using int 80h. Here's a way you can cheat if you just want to print a single digit:

  • 在.data节中,声明一个称为int2char的新字节:'int2char:db 0'
  • 从ecx中减去5后,通过加48将数字转换为ASCII(这将为您提供"5"而不是5)
  • 将ecx存储到int2char
  • 将int2char的地址移至ecx
  • 将edx设置为1,因为您只想打印1个字符

完成这项工作后,您将需要完成多于一位数字的转换.

Converting numbers with more than one digit will be left as an exercise for you once you get this working.

祝你好运!

这篇关于NASM中的输出数据寄存器值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆