Closed. This question needs to be more focused. It is not currently accepting answers. Learn more。
想改进这个问题吗?更新问题,使其只关注一个问题editing this post。
三年前关闭。
我通过编写C程序和查看程序集输出来学习汇编。为了使页面更容易,我在底部加入了C程序。我很难理解一种组装方式:
客户尽职调查
movzx eax,BYTE PTR[rbp-32+rax]铝合金movsx eax
所以我认为cdqe将eax扩展到rax(64位)。很明显,我想打印的字符串符合al寄存器,但我不明白rbp-32+rax的深层含义。有人能为我解释一下吗?
想改进这个问题吗?更新问题,使其只关注一个问题editing this post。
三年前关闭。
我通过编写C程序和查看程序集输出来学习汇编。为了使页面更容易,我在底部加入了C程序。我很难理解一种组装方式:
客户尽职调查
movzx eax,BYTE PTR[rbp-32+rax]铝合金movsx eax
所以我认为cdqe将eax扩展到rax(64位)。很明显,我想打印的字符串符合al寄存器,但我不明白rbp-32+rax的深层含义。有人能为我解释一下吗?
.file "string_manip.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "Hello"
.string ""
.zero 3
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 48
mov rax, QWORD PTR fs:40
mov QWORD PTR [rbp-8], rax
xor eax, eax
mov DWORD PTR [rbp-36], 0
mov eax, DWORD PTR .LC0[rip]
mov DWORD PTR [rbp-32], eax
movzx eax, WORD PTR .LC0[rip+4]
mov WORD PTR [rbp-28], ax
movzx eax, BYTE PTR .LC0[rip+6]
mov BYTE PTR [rbp-26], al
mov WORD PTR [rbp-25], 0
mov BYTE PTR [rbp-23], 0
mov DWORD PTR [rbp-36], 0
jmp .L2
.L3:
mov eax, DWORD PTR [rbp-36]
cdqe
movzx eax, BYTE PTR [rbp-32+rax] <--- what is this doing?
movsx eax, al
mov edi, eax
call putchar
add DWORD PTR [rbp-36], 1
.L2:
cmp DWORD PTR [rbp-36], 5
jle .L3
mov edi, 10
call putchar
mov eax, 0
mov rdx, QWORD PTR [rbp-8]
xor rdx, QWORD PTR fs:40
je .L5
call __stack_chk_fail
.L5:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4"
.section .note.GNU-stack,"",@progbits
#include <string.h>
#include <stdio.h>
int main()
{
int i = 0;
char array[10] = "Hello\0";
for(i=0; i<6; i++)
printf("%c", array[i]);
printf("\n");
return 0;
}
最佳答案
只是计算其中一个字符的地址。
假设您的字符串从rbp-32
开始,然后指令执行的C等价于ch = string[rax]
。
我想这是未优化的代码,所以编译器做了一些额外的符号扩展和零扩展,这是不需要的。
关于c - 了解这些组装说明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34564542/
10-11 18:48