我是汇编编程的新手(特别是x86_64)。我已将以下c程序翻译成汇编。
我理解了大部分代码,但我无法理解我已经注释掉的2条说明。
* stmnt 1 通过将 42 复制到其强大的 rax 注册内容低字?
注意:根据逻辑 stmnt 1 应在地址存储在 rax
addl $1,(%rax)
可以解释那两条指令。
#include<stdio.h>
int main()
{
int a=42,*ptr;
ptr = &a;
(*ptr)++;
return 0;
}
.file "temp.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $42, -20(%rbp)
leaq -20(%rbp), %rax
movq %rax, -16(%rbp)
movq -16(%rbp), %rax
movl (%rax), %eax ; stmt 1
leal 1(%rax), %edx ; stmt 2
movq -16(%rbp), %rax
movl %edx, (%rax)
movl $0, %eax
movq -8(%rbp), %rcx
xorq %fs:40, %rcx
je .L3
call __stack_chk_fail
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413"
.section .note.GNU-stack,"",@progbits
答案 0 :(得分:4)
是的,stmt1
正在覆盖rax
,但这不是问题。 stmt2
然后edx = eax + 1
使用lea
以棘手的方式进行edx
。 movl %edx, (%rax)
中的递增值将被写回(*ptr)++;
的内存中。这意味着rax = ptr; /* load pointer */
eax = *rax; /* fetch current value */
edx = eax + 1; /* calculate new value */
rax = ptr; /* load pointer again */
*rax = edx; /* write new value */
已分为多个步骤,如下所示:
addl $1,(%rax)
是的,可以使用void foo(int* ptr)
{
(*ptr)++;
}
。您可能没有启用优化,这就是您看到低效代码的原因。
启用优化后,输入以下代码:
addl $1, (%rdi)
ret
生成这个程序集:
void foo(int* ptr)
{
*ptr = 42;
(*ptr)++;
}
而且:
movl $43, (%rdi)
ret
给出:
private const int RECORDER_SAMPLERATE = 16000;
private const ChannelIn RECORDER_CHANNELS = ChannelIn.Mono;
private const Android.Media.Encoding RECORDER_AUDIO_ENCODING = Android.Media.Encoding.Pcm16bit;
...
var bufferSize = AudioRecord.GetMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
audioBuffer = new byte[bufferSize];
audioRecord = new AudioRecord(
// Hardware source of recording.
AudioSource.Mic,
// Frequency
RECORDER_SAMPLERATE,
// Mono or stereo
RECORDER_CHANNELS,
// Audio encoding
RECORDER_AUDIO_ENCODING,
// Length of the audio clip.
audioBuffer.Length
);
audioRecord.StartRecording();
...
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
while (true)
{
if (endRecording)
{
endRecording = false;
break;
}
try
{
// Keep reading the buffer while there is audio input.
int numBytes = await audioRecord.ReadAsync(audioBuffer, 0, audioBuffer.Length);
await fileStream.WriteAsync(audioBuffer, 0, numBytes);
// Do something with the audio input.
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
break;
}
}
fileStream.Close();
}
audioRecord.Stop();
audioRecord.Release();