x86程序集:在mul(seg错误)后将整数打印到控制台 [英] x86 assembly: printing integer to the console after mul (seg fault)

查看:126
本文介绍了x86程序集:在mul(seg错误)后将整数打印到控制台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习x86汇编.我正在使用的书是Assembly Language - Step by Step, Programming With Linux(我不得不说这很不错).到目前为止,我学到了很多东西,但是我觉得我还应该挑战自己,在很多方面保持领先,这样我就可以通过做得更快(我可以自上而下地学习,但是我发现这很乏味)慢).

I'm trying to learn x86 assembly. The book I'm using is Assembly Language - Step by Step, Programming With Linux (and I'd have to say it's pretty good). I've learned a lot so far, but I feel as though I should also be challenging myself to stay ahead in many respects so I can learn faster through doing (I can do follow along, top-down learning, but I find it tediously slow).

因此,我认为尝试将两个寄存器(32位)相乘然后将数据输出到控制台是一个不错的主意.

So, I figured it would be a cool idea to try and multiply two registers (32-bit) and then output the data to the console.

问题在于,当我执行程序时(就像本书一样,我正在使用NASM-尽管没有Insight调试器),但我收到了分段错误.我已经在 gdb 中做了很多调试工作,但是由于某种原因,我似乎无法弄清楚问题出在哪里.

The problem is that when I execute the program (I'm using NASM, just as the book does - no Insight debugger though), I receive a segmentation fault. I've done a fair amount of debugging in gdb with this little hammer out, but for whatever reason I can't seem to figure out what the issue is.

我想知道为什么我会遇到细分错误,以及一种好的方法是 谴责问题.另外,如果我在代码中所做的注释与实际发生的情况不符,我将不胜感激,如果有人可以对此进行纠正.

I'd like to know why I'm receiving a segmentation fault, and what a good way would be to reprimand the issue. Also, if the comments I've made in the code don't match up with what exactly is happening, I'd be grateful if anyone could correct me on that.

到目前为止,这是我的代码(评论不错)

Here's my code so far (it's well commented)

谢谢.

代码解码器

section .data
;TODO

section .bss
valueToPrint: resb 4            ;alloc 4 bytes of data in 'valueToPrint'

section .text

global _start

_mul:
    mov eax, 0x2A ;store 42 in eax
    mov edx, 0x2A ;store 42 in edx
    mul eax
    ret

_safe_exit:
    mov eax, 1  ;initiate 'exit' syscall
    mov ebx, 0  ;exit with error code 0
    int 0x80    ;invoke kernel to do its bidding 

_start:
    nop                         ;used to keep gdb from complaining

    call _mul                       ;multiply the values
    mov [valueToPrint], eax         ;store address of eax in the contents of valueToPrint
    mov eax, 4                      ;specify a system write call - aka syswrite
    mov ebx, 1                      ;direction used to make the syswrite call output to console - i.e. stdout
    mov dword [ecx], valueToPrint   ;store valueToPrint in ecx: ecx represents the syswrite register
    int 0x80                        ;invoke kernel based on the given parameters

    call _safe_exit

修改

此外,如果这有所作为,我正在运行Arch Linux.

Also, I'm running Arch Linux, if that makes a difference.

推荐答案

此行导致分段错误:

mov dword [ecx], valueToPrint

您告诉它将valueToPrint存储在地址ecx的存储位置中.您永远不会初始化ecx(内核可能会在您启动程序时将其初始化为0),因此,当取消引用它时,您将访问无效的内存位置.

You're telling it to store valueToPrint in the memory location at address ecx. You never initialize ecx (the kernel probably initializes it to 0 on program start for you), so when you dereference it, you're going to access an invalid memory location.

write(2) 系统调用采用3个参数:寄存器中的文件描述符号ebx,指向要在ecx中写入的字符串的指针,以及要在edx中写入的字节数.因此,如果只想打印结果的原始二进制数据,则可以传递valueToPrint的地址,并告诉它从该地址打印4个字节.在这种情况下,valueToPrint为1764(十六进制为0x6e4),因此此代码将在x86上打印出4个字节的e4 06 00 00,该字节为little-endian:

The write(2) system call takes 3 parameters: the file descriptor number in register ebx, a pointer to the string to write in ecx, and the number of bytes to write in edx. So, if you want to just print the raw binary data of the result, you can pass the address of valueToPrint, and tell it to print 4 bytes from that address. In this case, valueToPrint is 1764 (0x6e4 in hex), so this code would print out the 4 bytes e4 06 00 00 on x86, which is little-endian:

mov [valueToPrint], eax   ; store the result into memory
mov eax, 4                ; system call #4 = sys_write
mov ebx, 1                ; file descriptor 1 = stdout
mov ecx, valueToPrint     ; store *address* of valueToPrint into ecx
mov edx, 4                ; write out 4 bytes of data
int 0x80                  ; syscall

这篇关于x86程序集:在mul(seg错误)后将整数打印到控制台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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