完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
嗨,那里。我想问一下,阅读汇编代码有什么技巧吗?例如:这个C代码:翻译成:我试着读这个小片段,但是它很难理解。1。Goto 0xC12。XORLW 0x0(任何值XOLD与0是相同的值,如果W是0和gt;z=1;否则Z=0)3。BTFSC状态,0x2(我不知道Z中现在是什么值,因为我不知道W),如果Z=0∶1。XOLLW 0x6(我不知道这是怎么做的,为什么XOR可以在操作数0x6上做?)如果Z!= 0∶1。在这种情况下,这个变量Ledii i与函数KEY,ununkiti化完全无关,我不知道如何挖掘。请给我一些阅读汇编的提示,谢谢。
以上来自于百度翻译 以下为原文 Hi, there. I want to ask that is there any skill to read assembly code? For example: This C code: void KEY_UnlockInitialization(void){ while(KEYbits.INITIALIZATION != ON); KEYbits.INITIALIZATION = OFF; } is translated to: 10: void KEY_UnlockInitialization(void){ 11: while(KEYbits.INITIALIZATION != ON); 08C0 28C1 GOTO 0xC1 08C1 0020 MOVLB 0x0 08C2 1C4C BTFSS KEYbits, 0x0 08C3 28C5 GOTO 0xC5 08C4 28C6 GOTO 0xC6 08C5 28C1 GOTO 0xC1 12: KEYbits.INITIALIZATION = OFF; 08C6 104C BCF KEYbits, 0x0 13: } 08C7 0008 RETURN 86: case TEMP_TOO_HIGH_DURING_CHARGE: 87: switch(led_i){ 009E 28BF GOTO 0xBF 00BF 0020 MOVLB 0x0 00C0 0845 MOVF 0x45, W 00C1 3A00 XORLW 0x0 00C2 1903 BTFSC STATUS, 0x2 00C3 28C8 GOTO 0xC8 00C4 3A06 XORLW 0x6 00C5 1903 BTFSC STATUS, 0x2 00C6 28D0 GOTO 0xD0 00C7 28B7 GOTO 0xB7 00C8 0844 MOVF led_i, W 00C9 3A00 XORLW 0x0 00CA 1903 BTFSC STATUS, 0x2 00CB 289F GOTO 0x9F /*code Omitted*/ I tried to read this small snippet but it's so hard to understand. 1. GOTO 0xC1 2. XORLW 0x0 (any value XORed with 0 is the same value, if w is 0 -> z = 1; otherwise z = 0) 3. BTFSC STATUS, 0x2 (I don't know what value is in z now, because I don't know w) if z = 0: 1. XORLW 0x6 (I don't know what this doing, why XOR can do on operand 0x6?) if z != 0: 1. MOVF led_i, W(this variable led_i is totally not related to function KEY_UnlockInitialization) In this situation, I don't know how to dig in. Please give me some hint to read assembly, thank you. |
|
相关推荐
19个回答
|
|
|
看起来像嵌套的开关()语句。外部开关()语句中使用的表达式的数据类型是什么?TimeTotooHyHug收费是什么价值?内部开关()语句中使用的LeDyi的数据类型是什么?那么?我看不到在KEY-UNCONKITIALIZIZION()函数中使用的变量LeDyi。请阅读PIC数据表的“指令集摘要”章节。
以上来自于百度翻译 以下为原文 Look like you have nested switch() statements. What is the data type for the expression used in the outer switch() statement? What value is TEMP_TOO_HIGH_DURING_CHARGE? What is the data type of led_i used in the inner switch() statement? So? I don't see the variable led_i used in your KEY_UnlockInitialization() function. Read the "Instruction Set Summary" chapter of your PIC datasheet. |
|
|
|
|
|
HiTeTeTrad是在ASM学习编程的时候,用一些简单的东西练习LED闪光灯和用ADC通过电位器控制LED频率。但是让我们看看我是否能帮助你进入正确的状态。XORE和“0”不影响价值,而是更新。从W内容的Z标志通知XOR操作是在零测试之前进行的。这配置了一些类似IF(W=0)或IF(W)的东西。= 0),这取决于后续的代码。关于“Redii i”变量的问题,与这个“C”代码集无关,它可能是编译器的一个工件,它可能会提前更新它,以便在后面的“C”源中进行某些操作。它也可以暂时重用某些不在使用中的自动变量。有一点可能是误导性的,即汇编代码在执行方面可能出现无序。注意地址栏。发生在一些从对象文件读取的浏览器中。
以上来自于百度翻译 以下为原文 Hi Betetr way is to invest sometime in learning to program in ASM, practising with some simple things lie the led flashing and controling LED frequency with an potentiometer via an ADC. But let's see if I can help put you in the right state of mind. XORing with '0' doesn't affect the value but updates the Z flag from the contents of W. Notice the XOR operation is imediatly before a test for Zero. This configures something like if( W == 0) or if(W != 0), depending on the subsequent code. The question about the 'led_i' variable, beeing unrelated to this 'C' code snipset is probably an artifact of the compiler, it might be updating it in advance for some operation that apears latter in the 'C' source. It also can be temporary reusing some automatic variable not in use at the moment. One thing that can be misleading is that, the assembly code might appear out of order in terms of execution. Pay attention to the address column. Happens with some viewers that read it from object files. HIH Best regards Jorge |
|
|
|
|
|
到1: 0:是的,我把枚举和交换应用在一起,就像下面一样,这也让我感到困惑!莱德基是个局外人,我不知道他为什么在这里。事实上,我在阅读这一章的时候阅读了汇编。但还是做不到。
以上来自于百度翻译 以下为原文 To 1and0: Yes, and I applied enumeration and switch together, something like below. typedef enum{ // CHARGER_WAIT_COMM_CABLE_IN, CHARGER_WAIT_BATTERY_IN, BATTERY_IN, BATTERY_VOLTAGE_TOO_LOW, //under 14 BATTERY_VOLTAGE_TOO_HIGH, CHARGER_VOLTAGE_TOO_HIGH, BATTERY_OVER_CURRENT, TEMP_TOO_LOW_INITIAL, TEMP_TOO_HIGH_INITIAL, TEMP_TOO_HIGH_DURING_CHARGE, BATTERY_BEING_CHARGED, BATTERY_FULL, UV_OVERTIME, CV_OVERTIME, WHOLE_CHG_OVERTIME, COMMUNICATION_FAILED, CHARGER_CHARGING_BUT_NO_CURRENT, }LED_CASES; extern volatile LED_CASES led_case; switch(led_case){ case CHARGER_WAIT_BATTERY_IN: switch(led_i){ case 0: led_i = led_i + 10; LED_RED = ON; break; case 100: led_i = led_i + 10; LED_RED = OFF; break; case 250: led_i = led_i + 10; LED_RED = ON; break; case 350: led_i = led_i + 10; LED_RED = OFF; break; case 1850: led_i = 0; break; default: led_i = led_i + 10; break; } break; This makes me confused too! The led_i is an outsider, I don't know why he is here. Actually, I read assembly while reading this chapter. But still can't make it. |
|
|
|
|
|
JorgeF:我想问一个问题,如果W的内容是0B1111 0000,X0x0与XORD。我猜的操作如下:W:1111 0000:0000 0000 ---------R:1111,结果,Z标志是0。如果W的内容为0Bxxxxxxxx,并与0x6. w:xxxxxxxx:0000 0110 -------------RX:XXXXXAS结果,Z标志为0?如果以上是真的,在我的POST .XORLW 0x0(假设z=0(w)!= 0),因为我们不知道W中的值是什么,然后编译器做:XORLW 0x6为什么需要再次做这行?你已经知道Z是零,你再次做这个指令来更新Z到0?这是没有意义的。如果这行只是为了执行下一行:BTFSC状态,0x2,那么转到:Goto 0xB7,这是编译器风格的汇编代码的正常情况吗?
以上来自于百度翻译 以下为原文 To JorgeF: I want to ask a question. If the content of W is 0b1111 0000, and XORed with 0x0. The operation I guessed is below: W: 1111 0000 : 0000 0000 ----------------- R: 1111 0000 as a result, the Z flag is 0? If the content of W is 0bxxxx xxxx, and XORed with 0x6. W: xxxx xxxx : 0000 0110 ----------------- R: xxxx x11x as a result, the Z flag is 0? If above is true, in my post. XORLW 0x0 (assume that z = 0(w != 0), because we don't know what value in W) then the compiler do: XORLW 0x6 Why need to do this line again? You already know the z is zero and you do this instruction again to update z to 0? It doesn't make any sense. If this line is just for executing next line: BTFSC STATUS, 0x2 Then just go to: GOTO 0xB7 Is this a normal situation to compiler-style assembly code? |
|
|
|
|
|
我想问一个问题,如果W的内容是0B1111 0000,并用0x0进行XORD,那么我猜的操作如下:W:1111 0000:0000 0000 -----------R:1111,结果,Z标志是0。对的。结果不是ZeRo,所以不会设置零标志。不!您所做的操作是“或”,而不是“XOR”。您更改为“1”的两个比特将是W寄存器中的“X”位的补充。XOR用1补充值。XORLW 6仅在W包含6的情况下仅产生0。这不是真的,所以其余假设都是错误的。是的,它做了一些。设置或清除零标志的东西,然后使用“BTFSC状态,0x2”来选择跳过GOTO以有条件地影响程序流。
以上来自于百度翻译 以下为原文 I want to ask a question. If the content of W is 0b1111 0000, and XORed with 0x0. The operation I guessed is below: W: 1111 0000 : 0000 0000 ----------------- R: 1111 0000 as a result, the Z flag is 0? Correct. The result is not zeero, so the zero flag will not be set. No! The operation you have done is "OR", not "XOR" The two bits you changed to "1" will be the complement of the "x" bits in the W register. XOR with 1 complements a value. XORLW 6 will only produce zero if W originally contained 6. It's not true, so the rest of your assumptions are wrong. Yes, it does something which sets or clears the zero flag, then uses "BTFSC STATUS, 0x2" to optionally skip over a GOTO to conditionally affect program flow. |
|
|
|
|
|
|
|
|
|
|
|
异或OR真值表:B XOR NXOR0 0 0 1 10 1 01 0 0 1 01 1 0 1
以上来自于百度翻译 以下为原文 Truth table for exclusive or: A B XOR NXOR 0 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 |
|
|
|
|
|
XORLW K用于测试WRG中的值,以查看它是否等于K。如果WReg等于k,则零标志(状态,0x2)为1,否则零标志为0;即,它从POSTα1:86:CASE TimeTotoOh HythurnIn充电:87:开关(Redii){09E 28 BF得到了注释添加到您的反汇编代码。O 0xBF00 BF 0020 MOVLB 0x0;选择LEDYIO 0 C0 0845 MOVF 0x45,W;IF(高字节LeDyi i=高(0))0C1 3A00 XOLLW 0x0;1903 C2 1903 BTFSC状态,0x2;0C3 28 C8 GOTO 0xC8;Z=1 -gt;分支检查CALE000 0C4 3A06 XORLW 0x6的LEDYI低字节;否则(LEDIII=高字节)=高(100).00 C5 1903 BTFSC状态,0x2;0C628 D0 GOTO 0xD0;Z=1和-GT;检查CAE100100C7 8B7 GOTO 0xB7的LeDyI的低字节;Z=0 -Gt;分支检查下一个CASE E.C0 0844 MOVF Redii i,w;IF(低字节的Redii i=低(0))900C9 3A00 XORLW 0x0;0CA 1903 BTFSC状态,0x2;0CB 89F GOTO 0x9F;Z=1 & gt;分支执行CASE 0的代码
以上来自于百度翻译 以下为原文 XORLW k is used to test the value in WREG to see if it's equal to or not equal to k. If WREG equals to k the zero flag (STATUS,0x2) is 1, else the zero flag is 0; i.e. it performs if (WREG == k) Added comments to your disassembly code from Post #1: 86: case TEMP_TOO_HIGH_DURING_CHARGE: 87: switch(led_i){ 009E 28BF GOTO 0xBF 00BF 0020 MOVLB 0x0 ; select bank of led_i 00C0 0845 MOVF 0x45, W ; if (high byte of led_i == high(0)) 00C1 3A00 XORLW 0x0 ; 00C2 1903 BTFSC STATUS, 0x2 ; 00C3 28C8 GOTO 0xC8 ; Z = 1 -> branch to check low byte of led_i for case0 00C4 3A06 XORLW 0x6 ; else if (high byte of led_i == high(100)) 00C5 1903 BTFSC STATUS, 0x2 ; 00C6 28D0 GOTO 0xD0 ; Z = 1 -> branch to check low byte of led_i for case100 00C7 28B7 GOTO 0xB7 ; Z = 0 -> branch to check next case 00C8 0844 MOVF led_i, W ; if (low byte of led_i == low(0)) 00C9 3A00 XORLW 0x0 ; 00CA 1903 BTFSC STATUS, 0x2 ; 00CB 289F GOTO 0x9F ; Z = 1 -> branch to execute code of case0 |
|
|
|
|
|
这也让我感到困惑!Ledii i是一个局外人,我不知道他为什么在这里。为什么你一直认为Leqi i被用于KEY-UNCONKITIALIZATION()函数?该反汇编代码显示了属于Lwitter()语句的LeDyi,即No.QuixunOnKyTyItIraseId()函数。
以上来自于百度翻译 以下为原文 This makes me confused too! The led_i is an outsider, I don't know why he is here. Why you keep thinking led_i is used in the KEY_UnlockInitialization() function? That disassembly code shows led_i belong to the switch() statement, _not_ the KEY_UnlockInitialization() function. The disassembly code for KEY_UnlockInitialization() is shown in your Post #1, do you see led_i anywhere there? |
|
|
|
|
|
这是你的汇编代码,ASM注释:86:Twitter TooTooOa HythurdIn充电:87:开关(Leqi){09E 28 BF GOTO 0XBF00 BF 0020 MOVLB 0x0;BANSEL LeDi I000 C0 0845 MOVF 0x45,W;MOVF Ledii I+ 1,W00 C3A00 XOLLW 0x0;XORLW高(0)0C2 1903 BTFSC状态,0x2;SKPNZ00 C3 28 C8 GOTO 0xC8XORLW高(0)^高(100)=XORLW 600 C5 1903 BTFSC状态,0x2;SKPNZ00 C6 28 D0 GOTO 0xD0;分支检查低Case10000 C7 28 B7 GOTO 0xB7;分支检查下一个CaseCase0:00 C8 0844 MOVF Redii i,w;MOVF Ledii i+ 0,W00 C93A00 XOLLW 0x0;XOLLW低;(0)0CA 1903 BTFSC状态,0x2;SKPNZ00 CB 89F GOTO 0X9F;GTO TO CASE 0体
以上来自于百度翻译 以下为原文 And here's your disassembly code with asm comments: 86: case TEMP_TOO_HIGH_DURING_CHARGE: 87: switch(led_i){ 009E 28BF GOTO 0xBF 00BF 0020 MOVLB 0x0 ; banksel led_i 00C0 0845 MOVF 0x45, W ; movf led_i+1,w 00C1 3A00 XORLW 0x0 ; xorlw high(0) 00C2 1903 BTFSC STATUS, 0x2 ; skpnz 00C3 28C8 GOTO 0xC8 ; goto case0 00C4 3A06 XORLW 0x6 ; xorlw high(0) ^ high(100) = xorlw 6 00C5 1903 BTFSC STATUS, 0x2 ; skpnz 00C6 28D0 GOTO 0xD0 ; branch to check low case100 00C7 28B7 GOTO 0xB7 ; branch to check next case case0: 00C8 0844 MOVF led_i, W ; movf led_i+0,w 00C9 3A00 XORLW 0x0 ; xorlw low(0) 00CA 1903 BTFSC STATUS, 0x2 ; skpnz 00CB 289F GOTO 0x9F ; goto case0 body |
|
|
|
|
|
此外,对于您的交换机(Redii),Stand交换两个语句的顺序,将通过改进优化来减少程序内存使用。甚至更好地编辑:用+=替换了LeDyI= LeDyI+ 10。
以上来自于百度翻译 以下为原文 Furthermore, for your switch(led_i) statement switch(led_i){ case 0: led_i = led_i + 10; LED_RED = ON; break; case 100: led_i = led_i + 10; LED_RED = OFF; break; case 250: led_i = led_i + 10; LED_RED = ON; break; case 350: led_i = led_i + 10; LED_RED = OFF; break; case 1850: led_i = 0; break; default: led_i = led_i + 10; break; } swap the order of the two statements for led_i = led_i + 10; LED_RED = ON; and led_i = led_i + 10; LED_RED = OFF; will reduce program memory usage by improving optimization. Even better is switch(led_i) { case 1850: led_i = 0; break; case 0: case 250: LED_RED = ON; led_i += 10; break; case 100: case 350: LED_RED = OFF; led_i += 10; // these two statements are optional break; // as the optimizer will remove them default: led_i += 10; } Edit: Replaced led_i = led_i + 10 with +=. |
|
|
|
|
|
到1和0:Q1:在0C0,为什么IEDTI i递增1?Q2:你怎么知道地址0xC8是案例0的入口?我不能告诉它。Q3:在0C8,为什么这个时间F是由Ledii i表示的,而不是十六进制数,如线0C0?谢谢您。
以上来自于百度翻译 以下为原文 To 1and0: 86: case TEMP_TOO_HIGH_DURING_CHARGE: 87: switch(led_i){ 009E 28BF GOTO 0xBF 00BF 0020 MOVLB 0x0 ; banksel led_i 00C0 0845 MOVF 0x45, W ; movf led_i+1,w 00C1 3A00 XORLW 0x0 ; xorlw high(0) 00C2 1903 BTFSC STATUS, 0x2 ; skpnz 00C3 28C8 GOTO 0xC8 ; goto case0 00C4 3A06 XORLW 0x6 ; xorlw high(0) ^ high(100) = xorlw 6 00C5 1903 BTFSC STATUS, 0x2 ; skpnz 00C6 28D0 GOTO 0xD0 ; branch to check low case100 00C7 28B7 GOTO 0xB7 ; branch to check next case case0: 00C8 0844 MOVF led_i, W ; movf led_i+0,w 00C9 3A00 XORLW 0x0 ; xorlw low(0) 00CA 1903 BTFSC STATUS, 0x2 ; skpnz 00CB 289F GOTO 0x9F ; goto case0 body Q1: At 00C0, why ied_i is incremented by 1? Q2: How do you know address 0XC8 is the entry to case 0? I can't tell it. Q3: at 00C8, why this time f is represented by led_i, not hex number like line 00C0? Thank you. |
|
|
|
|
|
值不会全部递增。请参阅POST第9条中的注释。它正在读取16位变量的高位字节。低字节位于地址“Ledii i”,高位字节位于地址“Ledii I+ 1”,遵循代码所做的逻辑。如果高位字节为0,则跳转到地址为0C8,而在地址0C8上它的第一件事是检查L是否为L。OH字节也是零。这意味着整个变量“Ledii i”是零。这只是使用名称本身的反汇编程序,因为这次没有添加任何东西。我真的认为这是一种愚蠢的方式来尝试学习汇编程序,试图遵循编译器的代码输出。下面的代码实际上是在汇编程序中编写的,而不是反汇编程序如何解释编译器的代码输出。
以上来自于百度翻译 以下为原文 The value is not incremented all. See the comments in post#9. It is reading the high byte of your 16 bit variable. The low byte is at address "led_i" and the high byte is at address "led_i + 1" By following the logic of what the code is doing. It jumps to address 00C8 if the high byte is zero, and the very first thing it does at address 00C8 is to check if the low byte is also zero. That means the whole variable "led_i" is zero. That is just the disassembler using the name itself because nothing has been added to it this time. I really think this is a SILLY way to try to learn assembler, by trying to follow code output by a compiler. You need to become conversant in the language following code actually written in assembler, rather than how a disassembler interprets code output by a compiler. |
|
|
|
|
|
Qub:我不太明白这句话,你是在告诉我在汇编中写代码吗?
以上来自于百度翻译 以下为原文 To qub: I don't quite understand this sentence, are you telling me just go write code in assembly? |
|
|
|
|
|
我要说的是用汇编语言编写的教程,并尝试编写自己的教程。在理解编译器所做的事情之前,你需要了解语言。编译器将以不明显的方式来做事情,你需要有一些语言容易跟随的经验。
以上来自于百度翻译 以下为原文 I'm saying look at tutorials written in assembly language, and try writing your own. You need to understand the language before you can understand what the compiler is doing. The compiler will be doing things in un-obvious ways, that you need to have some experience with the language to follow easily. |
|
|
|
|
|
到1: 0:为什么0x6=100?高字节中的0x6应该是512+1024=1536(十进制)或600(十六进制)。
以上来自于百度翻译 以下为原文 To 1and0: 00C4 3A06 XORLW 0x6 ; else if (high byte of led_i == high(100)) Why 0x6 = 100? The 0x6 in high byte should be 512+1024=1536(decimal) or 600(hex) |
|
|
|
|
|
|
|
|
|
|
|
我怀疑这个评论是错误的。我不明白为什么它要检查高字节是否等于0x6。你没有在B7的位置发布代码,所以我们看不出它接下来会做什么。
以上来自于百度翻译 以下为原文 I suspect the comment is wrong. I can't see why it is checking if the high byte equals 0x6. You did not post the code at location B7, so we can't see what it does next. |
|
|
|
|
|
我的坏,100=0x00 64,我把上半字节6误认为是上字节。您必须发布更多代码或将.LST文件附加到完整的图片中。在任何情况下,逻辑都是相同的——它通过测试每个字节来检查每个案例。
以上来自于百度翻译 以下为原文 My bad, 100 = 0x0064 and I've mistaken the upper nibble 6 as the upper byte. You will have to post more code or attach the .lst file for a complete picture. In any case, the logic is the same -- it checks each case by testing its bytes. |
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473 浏览 0 评论
5793 浏览 9 评论
2334 浏览 8 评论
2224 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3530 浏览 3 评论
1124浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1095浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
873浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
475浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 05:37 , Processed in 1.214147 second(s), Total 108, Slave 91 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
654