我对gdb很新。我写了一个非常简单的你好世界节目
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class ViewDatabase extends AppCompatActivity {
private static final String TAG = "ViewDatabase";
private DatabaseReference databaseReference;
private String userID;
private ListView mListView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_database_layout);
mListView = (ListView) findViewById(R.id.listview);
databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
showData(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showData(DataSnapshot dataSnapshot) {
userinfo user = dataSnapshot.getValue(userinfo.class);
Log.d(TAG, "showData: name: " + user.getName());
Log.d(TAG, "showData: Mobile: " + user.getMob());
Log.d(TAG, "showData: Vehicle: " + user.getVehicle());
Log.d(TAG, "showData: Address: " + user.getaddress());
ArrayList < String > array = new ArrayList < > ();
array.add(user.getName());
array.add(user.getMob());
array.add(user.getVehicle());
array.add(user.getaddress());
ArrayAdapter adapter = new
ArrayAdapter(this, android.R.layout.simple_list_item_1, array);
mListView.setAdapter(adapter);
}
}
我用 public class userinfo {
public String name;
public String mob;
public String vehicle;
public String address;
public userinfo() {
}
public userinfo(String name, String mob, String vehicle, String address) {
this.name = name;
this.mob = mob;
this.vehicle = vehicle;
this.address = address;
}
public String getName() {
return name;
}
public String getMob() {
return mob;
}
public String getVehicle() {
return vehicle;
}
public String getaddress() {
return address;
}
}
}
编译它以添加调试符号
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
由于我不熟悉gdb,我不知道接下来要做什么。我希望能够使用gdb来检查汇编代码。这就是我在IRC上被告知的事情。
答案 0 :(得分:2)
首先,启动程序以准确停在main
函数的开头。
(gdb) start
切换到装配布局,以便在单独的窗口中以交互方式查看装配说明。
(gdb) layout asm
使用stepi
或nexti
命令逐步执行该程序。当您遍历程序中的汇编指令时,您将看到装配窗口中的当前指令指针移动。
答案 1 :(得分:2)
printf几乎是你想要用来学习汇编的最后一个函数,库调用会在以后出现,但你不需要使用库/系统调用。使用调试器将使用系统调用引导您进入鼠窝。尝试这样的事情,特别是如果你想通过这个练习学习汇编语言。
unsigned int fun ( unsigned int a, unsigned int b )
{
return(a^b^3);
}
gcc -O2 -c so.c -o so.o
objdump -D so.o
Disassembly of section .text:
0000000000000000 <fun>:
0: 89 f0 mov %esi,%eax
2: 83 f0 03 xor $0x3,%eax
5: 31 f8 xor %edi,%eax
7: c3 retq
我强烈建议您避免使用x86作为第一个指令集。尝试更干净的东西......
arm-none-eabi-gcc -O2 -c so.c -o so.o
arm-none-eabi-gcc -O2 -c -mthumb so.c -o so.o
arm-none-eabi-objdump -D so.o
00000000 <fun>:
0: 2303 movs r3, #3
2: 4059 eors r1, r3
4: 4048 eors r0, r1
6: 4770 bx lr
msp430-gcc -O2 -c so.c -o so.o
msp430-objdump -D so.o
00000000 <fun>:
0: 3f e0 03 00 xor #3, r15 ;#0x0003
4: 0f ee xor r14, r15
6: 30 41 ret
认真对待这一个是第一个指令集,msp430接近它但是这个最有意义,不幸的是gnu汇编语法与书不匹配,也不幸的是在八进制的世界思想然后我们认为hex现在...
pdp11-aout-gcc -O2 -c so.c -o so.o
pdp11-aout-objdump -D so.o
00000000 <_fun>:
0: 1166 mov r5, -(sp)
2: 1185 mov sp, r5
4: 15c0 0003 mov $3, r0
8: 1d41 0006 mov 6(r5), r1
c: 7840 xor r1, r0
e: 1d41 0004 mov 4(r5), r1
12: 7840 xor r1, r0
14: 1585 mov (sp)+, r5
16: 0087 rts pc
适合所有人的好模拟器或硬件,最好在模拟器中学习,而不是在真实硬件上学习......
我通过编写反汇编器,手臂和拇指学到的大部分指令集都属于这一类,因为它们是固定的指令长度(如果你避免使用thumb2扩展)。或者只是写一个模拟器,msp430和pdp11属于这一类。后者中的任何一个都是下午的项目,前者是一个长周末项目。你会比普通人更了解每个指令集,甚至一些人已经在其中编程了一段时间。
如果你坚持使用x86(我强烈建议你远离这个),请使用像pcemu这样的8086/8088模拟器并坚持原始指令集,使用nasm或a86或其他任何需要的方法来执行此操作。即使在那时它也没有那么好的指令集,但是当时比现在更有意义。 bitsavers很好地扫描了原始英特尔文档的搜索能力版本,这是最好的起点。
arm docs at arm(寻找armv5的架构参考手册,我认为他们现在称之为)。 msp430只是看看wikipedia指令集是否有pdp11谷歌它并使用C来机器代码来反汇编弄清楚语法。
如果你真的想玩得开心从opencores获得琥珀色核心它是一个arm2 / 3,几乎所有指令都与armv4相同,后来可以使用gnu工具。使用verilator从内部构建和模拟并查看工作处理器。理解这就像吸收100名程序员并为他们提供编程任务并获得1到100种不同的解决方案一样,采用指令集并为100名工程师提供实施任务的任务,您可以获得1到100种不同的解决方案。 Arm本身已经为相同的指令集多次重新设计了它们的核心,更不用说少数合法的克隆了。
建议订购pdp11,msp430,拇指,手臂,然后mips,如果你仍然觉得你需要拆解一些x86。 PIC12 / 14简单而有教育意义(应该花半个小时到一个小时来制作一个模拟器),6502,z80,8051,6800和其他一些历史上也很有教育意义的x86来查看文档但是没有必要编写程序。如果你从一个好的开始,那么每个第N个指令集从第二个指令集开始就容易得多。它们比不同的更相似,但你确实可以看到不同的东西,比如如何在没有标记的情况下做事情等等......我遗漏了其他一些指令集,这些指令集仍然可以在硅片中使用,或者由于各种原因而感兴趣。
另一种方法是安装clang / llvm并快速或长时间查看llc可以生成的每个指令集(编译为bitcode /字节码然后使用llc来执行任何指令集的后端)。像上面一样,使用相同的代码,看看不同的指令集看起来至少与编译器一样,它的设置非常有教育意义,有助于在心理上了解如何将编程任务分解为这些原子步骤。