NASM中的输出数据寄存器值

Hal*_*ude 5 linux assembly nasm

这里有新人,我已经有了一个问题.

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

下面的代码是什么,它打印出好的字符串,在ECX中推送值好,但是当它达到以下代码时:

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

                int 80h  
Run Code Online (Sandbox Code Playgroud)

它不会在终端上显示edx的内容,不过我认为我告诉它使用mov eax,4等.

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

代码(自2012年6月17日起修订):

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
Run Code Online (Sandbox Code Playgroud)

PS-如果我的线路缩进糟透了,我想知道如何改进它; 一旦你克服了最初的学习"驼峰",恕我直言学习集会变得更有吸引力:)

Mul*_*ike 2

首先,感谢你的问题——它激励我学习 int 80h,这是我以前不熟悉的东西。

您的程序以当前形式执行什么操作?它打印任何东西吗?如果我在脑海中正确执行它,我希望它打印第一条消息,然后崩溃。由于缓冲,它甚至可能不会显示可疑崩溃之前的第一条消息。

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

ssize_t write(int fd, const void *buf, size_t count);
Run Code Online (Sandbox Code Playgroud)

因此,eax = 4,ebx = fd,ecx = buf,edx = count。如果您想对代码注释更加迂腐,“mov eax,4”表示“将字符串写入文件”,而“mov ebx,1”表示“指定文件#1,该文件映射到 STDOUT(终端)” 。

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

另外,如果我正确阅读 int 80h 文档,则示例中的推送/弹出堆栈操作没有任何相关性。

在 ASM 中将数字打印为字符串有点麻烦。您需要将数字转换为字符串,然后可以使用 int 80h 打印它。如果您只想打印一个数字,可以采用以下作弊方法:

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

一旦你开始工作,转换多于一位数字的数字将作为练习留给你。

祝你好运!