54772


アセンブラを独学中です。大学で情報をやっているわけでもないのであまり専門用語を使う際は簡単な説明を入れてもらえると助かります。

Hello, worldを10回表示させるプログラムを書きましたが  
rcxをsyscallの前後でスタックから出し入れする必要がありました。これはなぜでしょうか？

[code]

    global _main
    section .text
    _main:
        mov rcx, 10
    
    loop_label:
        mov     rax, 0x2000004
        mov     rdi, 1
        mov     rsi, msg
        mov     rdx, msg.len
    
        push rcx       ; to avoid register rcx from changing
        syscall
        pop rcx        ; to avoid register rcx from changing
    
        ; inc rcx
        cmp rcx, 10
        loop loop_label
    
        mov     rax, 0x2000001
        mov     rdi, 0
        syscall
    
    
    section .data
    msg:    db      "Hello, world!", 10
    .len:   equ     $ - msg
    
[/code]


CC BY-SA 4.0
2019-05-06T07:03:02.623
54768
2019-05-06T09:01:54.320
question
x86 gdb
なぜrcxをpushする必要があるのか？


短い答え  
Linux の `syscall` の仕様で `rcx` は `syscall` の前後で保存されないからです。

長い答え  
[The Definitive Guide to Linux System
Calls](https://blog.packagecloud.io/eng/2016/04/05/the-definitive-guide-to-
linux-system-calls/)

Linux の 64bit ユーザーソフトウエア (Ring3) が Linux Kernel (Ring0) を呼び出す目的で `syscall`
命令を発行するときの仕様が解説されています。引数の渡し方、結果の受け取り方、レジスタ保存則などなど。で、ここの説明によると `syscall` から戻った時
`rcx` と `r11` の値は壊されてしまうとあります。あなたのプログラムは `rcx` の値が変わってしまうとうまく動かない構造になっているので
`push`/`pop` が必要なわけです。


CC BY-SA 4.0
2019-05-06T09:01:54.320
54772
2019-05-06T09:01:54.320
8589
54768
answer